[ Index ] |
PHP Cross Reference of Textpattern 4.0.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * class wet_thumb 4 * @author C. Erdmann 5 * @see <a href="http://www.cerdmann.de/thumb">http://www.cerdmann.de/thumb</a> 6 * @author Robert Wetzlmayr 7 * 8 * refactored from function.thumb.php by C. Erdmann, which contained the following credit & licensing terms: 9 * === 10 * Smarty plugin "Thumb" 11 * Purpose: creates cached thumbnails 12 * Home: http://www.cerdmann.com/thumb/ 13 * Copyright (C) 2005 Christoph Erdmann 14 * 15 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. 16 * 17 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 20 * ------------------------------------------------------------- 21 * Author: Christoph Erdmann (CE) <smarty@cerdmann.com> 22 * Internet: http://www.cerdmann.com 23 * 24 * Author: Benjamin Fleckenstein (BF) 25 * Internet: http://www.benjaminfleckenstein.de 26 * 27 * Author: Marcus Gueldenmeister (MG) 28 * Internet: http://www.gueldenmeister.de/marcus/ 29 * 30 * Author: Andreas Bösch (AB) 31 * 32 */ 33 34 /* 35 $HeadURL: https://textpattern.googlecode.com/svn/releases/4.0.8/source/textpattern/lib/class.thumb.php $ 36 $LastChangedRevision: 3041 $ 37 */ 38 39 $verbose = false; 40 41 42 class wet_thumb { 43 var $width; // The width of your thumbnail. The height (if not set) will be automatically calculated. 44 var $height; // The height of your thumbnail. The width (if not set) will be automatically calculated. 45 var $longside; // Set the longest side of the image if width, height and shortside is not set. 46 var $shortside; // Set the shortest side of the image if width, height and longside is not set. 47 var $extrapolate; // Set to 'false' if your source image is smaller than the calculated thumb and you do not want the image to get extrapolated. 48 var $crop; // If set to 'true', image will be cropped in the center to destination width and height params, while keeping aspect ratio. Otherwise the image will get resized. 49 var $sharpen; // Set to 'false' if you don't want to use the Unsharp-Mask. Thumbnail creation will be faster, but quality is reduced. 50 var $hint; // If set to 'false' the image will not have a lens-icon. 51 var $addgreytohint; // Set to 'false' to get no lightgrey bottombar. 52 var $quality; // JPEG image quality (0...100, defaults to 80). 53 // link related params 54 var $linkurl; // Set to your target URL (a href="linkurl") 55 var $html; // Will be inserted in the image-tag 56 57 var $types = array('','.gif','.jpg','.png'); 58 var $_SRC; 59 var $_DST; 60 61 /** 62 * constructor 63 */ 64 function wet_thumb( ) { 65 $this->extrapolate = false; 66 $this->crop = true; 67 $this->sharpen = true; 68 $this->hint = true; 69 $this->addgreytohint = true; 70 $this->quality = 80; 71 $this->html = " alt=\"\" title=\"\" "; 72 $this->link = true; 73 } 74 75 /** 76 * write thumbnail file 77 * @param infile image file name 78 * @param outfile array of thumb file names (1...n) 79 * @return boolean, true indicates success 80 */ 81 function write( $infile, $outfile ) { 82 global $verbose; 83 84 if( $verbose )echo "writing thumb nail..."; 85 86 ### fetch source (SRC) info 87 $temp = getimagesize($infile); 88 89 $this->_SRC['file'] = $infile; 90 $this->_SRC['width'] = $temp[0]; 91 $this->_SRC['height'] = $temp[1]; 92 $this->_SRC['type'] = $temp[2]; // 1=GIF, 2=JPG, 3=PNG, SWF=4 93 $this->_SRC['string'] = $temp[3]; 94 $this->_SRC['filename'] = basename($infile); 95 //$this->_SRC['modified'] = filemtime($infile); 96 97 //check image orientation 98 if ($this->_SRC['width'] >= $this->_SRC['height']) { 99 $this->_SRC['format'] = 'landscape'; 100 } else { 101 $this->_SRC['format'] = 'portrait'; 102 } 103 104 ### fetch destination (DST) info 105 if (is_numeric($this->width) AND empty($this->height)) { 106 $this->_DST['width'] = $this->width; 107 $this->_DST['height'] = round($this->width/($this->_SRC['width']/$this->_SRC['height'])); 108 } 109 elseif (is_numeric($this->height) AND empty($this->width)) { 110 $this->_DST['height'] = $this->height; 111 $this->_DST['width'] = round($this->height/($this->_SRC['height']/$this->_SRC['width'])); 112 } 113 elseif (is_numeric($this->width) AND is_numeric($this->height)) { 114 $this->_DST['width'] = $this->width; 115 $this->_DST['height'] = $this->height; 116 } 117 elseif (is_numeric($this->longside) AND empty($this->shortside)) { 118 // preserve aspect ratio based on provided height 119 if ($this->_SRC['format'] == 'portrait') { 120 $this->_DST['height'] = $this->longside; 121 $this->_DST['width'] = round($this->longside/($this->_SRC['height']/$this->_SRC['width'])); 122 } 123 else { 124 $this->_DST['width'] = $this->longside; 125 $this->_DST['height'] = round($this->longside/($this->_SRC['width']/$this->_SRC['height'])); 126 } 127 } 128 elseif (is_numeric($this->shortside)) { 129 // preserve aspect ratio based on provided width 130 if ($this->_SRC['format'] == 'portrait') { 131 $this->_DST['width'] = $this->shortside; 132 $this->_DST['height'] = round($this->shortside/($this->_SRC['width']/$this->_SRC['height'])); 133 } 134 else { 135 $this->_DST['height'] = $this->shortside; 136 $this->_DST['width'] = round($this->shortside/($this->_SRC['height']/$this->_SRC['width'])); 137 } 138 } 139 else { // default dimensions 140 $this->width = 100; 141 $this->_DST['width'] = $this->width; 142 $this->_DST['height'] = round($this->width/($this->_SRC['width']/$this->_SRC['height'])); 143 } 144 145 146 // don't make the new image larger than the original image 147 if ($this->extrapolate === false && $this->_DST['height'] > $this->_SRC['height'] && 148 $this->_DST['width'] > $this->_SRC['width']) { 149 $this->_DST['width'] = $this->_SRC['width']; 150 $this->_DST['height'] = $this->_SRC['height']; 151 } 152 153 $this->_DST['type'] = $this->_SRC['type']; 154 $this->_DST['file'] = $outfile; 155 156 // make sure we have enough memory if the image is large 157 if (max($this->_SRC['width'], $this->_SRC['height']) > 1024) 158 // this won't work on all servers but it's worth a try 159 ini_set('memory_limit', EXTRA_MEMORY); 160 161 // read SRC 162 if ($this->_SRC['type'] == 1) $this->_SRC['image'] = imagecreatefromgif($this->_SRC['file']); 163 elseif ($this->_SRC['type'] == 2) $this->_SRC['image'] = imagecreatefromjpeg($this->_SRC['file']); 164 elseif ($this->_SRC['type'] == 3) $this->_SRC['image'] = imagecreatefrompng($this->_SRC['file']); 165 166 // crop image? 167 $off_w = 0; 168 $off_h = 0; 169 if($this->crop != false) { 170 if($this->_SRC['height'] < $this->_SRC['width']) { 171 $ratio = (double)($this->_SRC['height'] / $this->_DST['height']); 172 $cpyWidth = round($this->_DST['width'] * $ratio); 173 if ($cpyWidth > $this->_SRC['width']) { 174 $ratio = (double)($this->_SRC['width'] / $this->_DST['width']); 175 $cpyWidth = $this->_SRC['width']; 176 $cpyHeight = round($this->_DST['height'] * $ratio); 177 $off_w = 0; 178 $off_h = round(($this->_SRC['height'] - $cpyHeight) / 2); 179 $this->_SRC['height'] = $cpyHeight; 180 } 181 else { 182 $cpyHeight = $this->_SRC['height']; 183 $off_w = round(($this->_SRC['width'] - $cpyWidth) / 2); 184 $off_h = 0; 185 $this->_SRC['width']= $cpyWidth; 186 } 187 } 188 else { 189 $ratio = (double)($this->_SRC['width'] / $this->_DST['width']); 190 $cpyHeight = round($this->_DST['height'] * $ratio); 191 if ($cpyHeight > $this->_SRC['height']) { 192 $ratio = (double)($this->_SRC['height'] / $this->_DST['height']); 193 $cpyHeight = $this->_SRC['height']; 194 $cpyWidth = round($this->_DST['width'] * $ratio); 195 $off_w = round(($this->_SRC['width'] - $cpyWidth) / 2); 196 $off_h = 0; 197 $this->_SRC['width']= $cpyWidth; 198 } 199 else { 200 $cpyWidth = $this->_SRC['width']; 201 $off_w = 0; 202 $off_h = round(($this->_SRC['height'] - $cpyHeight) / 2); 203 $this->_SRC['height'] = $cpyHeight; 204 } 205 } 206 } 207 208 // ensure non-zero height/width 209 if (!$this->_DST['height']) $this->_DST['height'] = 1; 210 if (!$this->_DST['width']) $this->_DST['width'] = 1; 211 212 // create DST 213 $this->_DST['image'] = imagecreatetruecolor($this->_DST['width'], $this->_DST['height']); 214 imagecopyresampled($this->_DST['image'], $this->_SRC['image'], 0, 0, $off_w, $off_h, $this->_DST['width'], $this->_DST['height'], $this->_SRC['width'], $this->_SRC['height']); 215 if ($this->sharpen === true) { 216 $this->_DST['image'] = UnsharpMask($this->_DST['image'],80,.5,3); 217 } 218 219 // finally: the real dimensions 220 $this->height = $this->_DST['height']; 221 $this->width = $this->_DST['width']; 222 223 // add magnifying glass? 224 if ( $this->hint === true) { 225 // should we really add white bars? 226 if ( $this->addgreytohint === true ) { 227 $trans = imagecolorallocatealpha($this->_DST['image'], 255, 255, 255, 25); 228 imagefilledrectangle($this->_DST['image'], 0, $this->_DST['height']-9, $this->_DST['width'], $this->_DST['height'], $trans); 229 } 230 231 $magnifier = imagecreatefromstring(gzuncompress(base64_decode("eJzrDPBz5+WS4mJgYOD19HAJAtLcIMzBBiRXrilXA1IsxU6eIRxAUMOR0gHkcxZ4RBYD1QiBMOOlu3V/gIISJa4RJc5FqYklmfl5CiGZuakMBoZ6hkZ6RgYGJs77ex2BalRBaoLz00rKE4tSGXwTk4vyc1NTMhMV3DKLUsvzi7KLFXwjFEAa2svWnGdgYPTydHEMqZhTOsE++1CAyNHzm2NZjgau+dAmXlAwoatQmOld3t/NPxlLMvY7sovPzXHf7re05BPzjpQTMkZTPjm1HlHkv6clYWK43Zt16rcDjdZ/3j2cd7qD4/HHH3GaprFrw0QZDHicORXl2JsPsveVTDz//L3N+WpxJ5Hff+10Tjdd2/Vi17vea79Om5w9zzyne9GLnWGrN8atby/ayXPOsu2w4quvVtxNCVVz5nAf3nDpZckBCedpqSc28WTOWnT7rZNXZSlPvFybie9EFc6y3bIMCn3JAoJ+kyyfn9qWq+LZ9Las26Jv482cDRE6Ci0B6gVbo2oj9KabzD8vyMK4ZMqMs2kSvW4chz88SXNzmeGjtj1QZK9M3HHL8L7HITX3t19//VVY8CYDg9Kvy2vDXu+6mGGxNOiltMPsjn/t9eJr0ja/FOdi5TyQ9Lz3fOqstOr99/dnro2vZ1jy76D/vYivPsBoYPB09XNZ55TQBAAJjs5s</body>"))); 232 imagealphablending($this->_DST['image'], true); 233 imagecopy($this->_DST['image'], $magnifier, $this->_DST['width']-15, $this->_DST['height']-14, 0, 0, 11, 11); 234 imagedestroy($magnifier); 235 } 236 237 if ($verbose ) echo "... saving image ..."; 238 239 if ($this->_DST['type'] == 1) { 240 imagetruecolortopalette($this->_DST['image'], false, 256); 241 if ( function_exists ('imagegif') ) { 242 imagegif($this->_DST['image'], $this->_DST['file']); 243 } else { 244 imagedestroy($this->_DST['image']); 245 imagedestroy($this->_SRC['image']); 246 return false; 247 } 248 } 249 elseif ($this->_DST['type'] == 2) { 250 imagejpeg($this->_DST['image'], $this->_DST['file'], $this->quality); 251 } 252 elseif ($this->_DST['type'] == 3) { 253 imagepng($this->_DST['image'], $this->_DST['file']); 254 } 255 256 if ($verbose ) echo "... image successfully saved ..."; 257 258 imagedestroy($this->_DST['image']); 259 imagedestroy($this->_SRC['image']); 260 return true; 261 } 262 263 /** 264 * return a reference to the the thumbnailimage as a HTML <a> or <img> tag 265 * @param aslink return an anchor tag to the source image 266 * @param aspopup open link in new window 267 * @return string with suitable HTML markup 268 */ 269 function asTag( $aslink = true, $aspopup = false ) 270 { 271 $imgtag = "<img src=\"" . $this->_DST['file']. "\" " . 272 $this->html . " " . 273 "width=\"".$this->width."\" " . 274 "height=\"".$this->height."\" " . 275 "/>"; 276 277 if ( $aslink === true ) { 278 return "<a href=\"" . ((empty($this->linkurl)) ? $this->_SRC['file'] : $this->linkurl) . "\" " . 279 (($aspopup === true) ? "target=\"_blank\"" : "") . ">" . 280 $imgtag . 281 "</a>"; 282 } 283 else { 284 return $imgtag; 285 } 286 } 287 } 288 /** 289 * class txp_thumb: wrapper for wet_thumb interfacing the TxP repository 290 */ 291 class txp_thumb extends wet_thumb { 292 293 var $m_ext; 294 var $m_id; 295 296 /*** 297 * constructor 298 * @param $id image id 299 */ 300 function txp_thumb ($id) { 301 $id = assert_int($id); 302 $rs = safe_row('*', 'txp_image', 'id = '.$id.' limit 1'); 303 if ($rs) { 304 extract($rs); 305 $this->m_ext = $ext; 306 $this->m_id = $id; 307 } 308 $this->wet_thumb(); // construct base class instance 309 } 310 311 /** 312 * create thumbnail image from source image 313 * @return boolean, true indicates success 314 */ 315 function write( ) { 316 if ( !isset($this->m_ext) ) return false; 317 318 if ( parent::write ( IMPATH.$this->m_id.$this->m_ext, IMPATH.$this->m_id.'t'.$this->m_ext ) ) { 319 safe_update('txp_image', 'thumbnail = 1', 'id = '.$this->m_id); 320 chmod(IMPATH.$this->m_id.'t'.$this->m_ext, 0644); 321 return true; 322 } 323 return false; 324 } 325 326 /** 327 * delete thumbnail 328 * @return boolean, true indicates success 329 */ 330 function delete( ) { 331 if (!isset($this->m_ext)) return false; 332 333 if (unlink(IMPATH.$this->m_id.'t'.$this->m_ext)) { 334 safe_update('txp_image', 'thumbnail = 0', 'id = '.$this->m_id); 335 return true; 336 } 337 return false; 338 } 339 340 } 341 342 /** 343 * Unsharp mask algorithm by Torstein Hønsi 2003 (thoensi_at_netcom_dot_no) 344 * Christoph Erdmann: changed it a little, cause i could not reproduce the 345 * darker blurred image, now it is up to 15% faster with same results 346 * @param img image as a ressource 347 * @param amount filter parameter 348 * @param radius filter parameter 349 * @param treshold filter parameter 350 * @return sharpened image as a ressource 351 * 352 * 353 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. 354 */ 355 356 function UnsharpMask($img, $amount, $radius, $threshold) { 357 // Attempt to calibrate the parameters to Photoshop: 358 if ($amount > 500) $amount = 500; 359 $amount = $amount * 0.016; 360 if ($radius > 50) $radius = 50; 361 $radius = $radius * 2; 362 if ($threshold > 255) $threshold = 255; 363 364 $radius = abs(round($radius)); // Only integers make sense. 365 if ($radius == 0) { return $img; imagedestroy($img); break; } 366 $w = imagesx($img); $h = imagesy($img); 367 $imgCanvas = $img; 368 $imgCanvas2 = $img; 369 $imgBlur = imagecreatetruecolor($w, $h); 370 371 // Gaussian blur matrix: 372 // 1 2 1 373 // 2 4 2 374 // 1 2 1 375 376 // Move copies of the image around one pixel at the time and merge them with weight 377 // according to the matrix. The same matrix is simply repeated for higher radii. 378 for ($i = 0; $i < $radius; $i++) 379 { 380 imagecopy ($imgBlur, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1); // up left 381 imagecopymerge ($imgBlur, $imgCanvas, 1, 1, 0, 0, $w, $h, 50); // down right 382 imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left 383 imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 1, $w, $h - 1, 25); // up right 384 imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left 385 imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 0, $w, $h, 25); // right 386 imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 20 ); // up 387 imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 16.666667); // down 388 imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 0, $w, $h, 50); // center 389 } 390 $imgCanvas = $imgBlur; 391 392 // Calculate the difference between the blurred pixels and the original 393 // and set the pixels 394 for ($x = 0; $x < $w; $x++) { // each row 395 for ($y = 0; $y < $h; $y++) { // each pixel 396 $rgbOrig = ImageColorAt($imgCanvas2, $x, $y); 397 $rOrig = (($rgbOrig >> 16) & 0xFF); 398 $gOrig = (($rgbOrig >> 8) & 0xFF); 399 $bOrig = ($rgbOrig & 0xFF); 400 $rgbBlur = ImageColorAt($imgCanvas, $x, $y); 401 $rBlur = (($rgbBlur >> 16) & 0xFF); 402 $gBlur = (($rgbBlur >> 8) & 0xFF); 403 $bBlur = ($rgbBlur & 0xFF); 404 405 // When the masked pixels differ less from the original 406 // than the threshold specifies, they are set to their original value. 407 $rNew = (abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig; 408 $gNew = (abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig; 409 $bNew = (abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig; 410 411 if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) { 412 $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew); 413 ImageSetPixel($img, $x, $y, $pixCol); 414 } 415 } 416 } 417 return $img; 418 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu May 21 23:03:01 2009 | Cross-referenced by PHPXref 0.7 |