ngg_Thumbnail

PHP class for dynamically resizing, cropping, and rotating images for thumbnail purposes and either displaying them on-the-fly or saving them.

Defined (2)

The class is defined in the following location(s).

/lib/imagemagick.inc.php  
  1. class ngg_Thumbnail { 
  2. /** 
  3. * Error message to display, if any 
  4. * @var string 
  5. */ 
  6. var $errmsg; 
  7. /** 
  8. * Whether or not there is an error 
  9. * @var boolean 
  10. */ 
  11. var $error; 
  12. /** 
  13. * File name and path of the image file 
  14. * @var string 
  15. */ 
  16. var $fileName; 
  17. /** 
  18. * Image meta data if any is available (jpeg/tiff) via the exif library 
  19. * @var array 
  20. */ 
  21. var $imageMeta; 
  22. /** 
  23. * Current dimensions of working image 
  24. * @var array 
  25. */ 
  26. var $currentDimensions; 
  27. /** 
  28. * New dimensions of working image 
  29. * @var array 
  30. */ 
  31. var $newDimensions; 
  32. /** 
  33. * Percentage to resize image b 
  34. * @var int 
  35. * @access private 
  36. */ 
  37. var $percent; 
  38. /** 
  39. * Maximum width of image during resize 
  40. * @var int 
  41. * @access private 
  42. */ 
  43. var $maxWidth; 
  44. /** 
  45. * Maximum height of image during resize 
  46. * @var int 
  47. * @access private 
  48. */ 
  49. var $maxHeight; 
  50. /** 
  51. * Image for Watermark 
  52. * @var string 
  53. */ 
  54. var $watermarkImgPath; 
  55. /** 
  56. * Text for Watermark 
  57. * @var string 
  58. */ 
  59. var $watermarkText; 
  60. /** 
  61. * Path to ImageMagick convert 
  62. * @var string 
  63. */ 
  64. var $imageMagickDir; 
  65. /** 
  66. * String to execute ImageMagick convert. 
  67. * @var string 
  68. */ 
  69. var $imageMagickExec; 
  70. /** 
  71. * String to execute ImageMagick composite. 
  72. * @var string 
  73. */ 
  74. var $imageMagickComp; 
  75. /** 
  76. * String to execute ImageMagick (before the filename). 
  77. * @var string 
  78. */ 
  79. var $imageMagickBefore; 
  80.  
  81. /** 
  82. * in: filename, error 
  83. * out: nothing  
  84. * init of class: init of variables, detect needed memory (gd), image format (gd), detect image size (GetImageSize is general PHP, not GD), Image Meta? 
  85. */ 
  86.  
  87. function ngg_Thumbnail($fileName, $no_ErrorImage = false) { 
  88.  
  89. //initialize variables 
  90. $this->errmsg = ''; 
  91. $this->error = false; 
  92. $this->currentDimensions = array(); 
  93. $this->newDimensions = array(); 
  94. $this->fileName = $fileName; 
  95. $this->imageMeta = array(); 
  96. $this->percent = 100; 
  97. $this->maxWidth = 0; 
  98. $this->maxHeight = 0; 
  99. $this->watermarkImgPath = ''; 
  100. $this->watermarkText = ''; 
  101. $this->imageMagickExec = ''; 
  102. $this->imageMagickComp = ''; 
  103. $this->imageMagickBefore = ''; 
  104.  
  105. //make sure ImageMagick is installed 
  106. $this->checkVersion(); 
  107.  
  108. //check to see if file exists 
  109. if(!file_exists($this->fileName)) { 
  110. $this->errmsg = 'File not found'; 
  111. $this->error = true; 
  112. //check to see if file is readable 
  113. elseif(!is_readable($this->fileName)) { 
  114. $this->errmsg = 'File is not readable'; 
  115. $this->error = true; 
  116.  
  117. if($this->error == false) {  
  118. $size = GetImageSize($this->fileName); 
  119. $this->currentDimensions = array('width'=>$size[0], 'height'=>$size[1]); 
  120.  
  121. if($this->error == true) { 
  122. // for SinglePic send the error message out 
  123. if(!$no_ErrorImage)  
  124. echo $this->errmsg; 
  125. return; 
  126.  
  127. function checkVersion() { 
  128.  
  129. // very often exec()or passthru() is disabled. No chance for Imagick 
  130. if ( ini_get('disable_functions') ) { 
  131. $not_allowed = ini_get('disable_functions'); 
  132. if ( stristr($not_allowed, 'exec') || stristr($not_allowed, 'passthru') ) { 
  133. $this->errmsg = 'exec() or passthru() is not allowed. Could not execute Imagick'; 
  134. $this->error = true; 
  135. return false; 
  136.  
  137. // get the path to imageMagick 
  138. $ngg_options = get_option('ngg_options'); 
  139. $this->imageMagickDir = trim( $ngg_options['imageMagickDir']); 
  140. $this->imageMagickDir = str_replace( "\\", "/", $this->imageMagickDir ); 
  141.  
  142. // Try to get the ImageMagick version  
  143. $magickv = $this->execute('convert', '-version'); 
  144.  
  145. if ( empty($magickv) ) { 
  146. $this->errmsg = 'Could not execute ImageMagick. Check path '; 
  147. $this->error = true; 
  148. return false; 
  149.  
  150. // We need as least version 6 or higher  
  151. $helper = preg_match('/Version: ImageMagick ([0-9])/', $magickv[0], $magickversion); 
  152. if ( !$magickversion[0] > '5' ) { 
  153. $this->errmsg = 'Require ImageMagick Version 6 or higher'; 
  154. $this->error = true; 
  155. return false; 
  156.  
  157. return true; 
  158.  
  159.  
  160. /** 
  161. * Execute ImageMagick/GraphicsMagick commands 
  162. * @param string $cmd an ImageMagick command (eg. "convert") 
  163. * @param string $args the arguments which should be passed 
  164. * @param bool *passthru(optional) output the result to the webserver instead 
  165. * @return void | if passthru return the image 
  166. */ 
  167. function execute( $cmd, $args, $passthru = false) { 
  168.  
  169. // in error case we do not continue 
  170. if($this->error == true) 
  171. return; 
  172.  
  173. //if path is not empty 
  174. if ($this->imageMagickDir != '') { 
  175. // the path must have a slash at the end 
  176. if ( $this->imageMagickDir{strlen($this->imageMagickDir)-1} != '/') 
  177. $this->imageMagickDir .= '/'; 
  178.  
  179. //$args = escapeshellarg($args); 
  180. //var_dump( escapeshellcmd ( "{$this->imageMagickDir}/{$cmd} {$args}" ) ); return; 
  181. //$this->errmsg = escapeshellcmd( "{$this->imageMagickDir}{$cmd} {$args}" ); 
  182.  
  183. if ( !$passthru ) { 
  184. exec( "{$this->imageMagickDir}{$cmd} {$args}", $result ); 
  185. //var_dump( "{$this->imageMagickDir}/{$cmd} {$args}" ); 
  186. return $result; 
  187.  
  188. //var_dump( escapeshellcmd ( "{$this->imageMagickDir}/{$cmd} {$args}" ) ); return; 
  189.  
  190. // for single pic we need the direct output 
  191. header('Content-type: image/jpeg'); 
  192. $this->errmsg = "{$this->imageMagickDir}{$cmd} {$args}"; 
  193. passthru( "{$this->imageMagickDir}{$cmd} {$args}" ); 
  194.  
  195.  
  196. /** 
  197. * Must be called to free up allocated memory after all manipulations are done 
  198. */ 
  199. function destruct() { 
  200. //not needed for ImageMagick 
  201. return; 
  202.  
  203. /** 
  204. * Returns the current width of the image 
  205. * @return int 
  206. */ 
  207. function getCurrentWidth() { 
  208. return $this->currentDimensions['width']; 
  209.  
  210. /** 
  211. * Returns the current height of the image 
  212. * @return int 
  213. */ 
  214. function getCurrentHeight() { 
  215. return $this->currentDimensions['height']; 
  216.  
  217. /** 
  218. * Calculates new image width 
  219. * @param int $width 
  220. * @param int $height 
  221. * @return array 
  222. */ 
  223. function calcWidth($width, $height) { 
  224. $newWp = (100 * $this->maxWidth) / $width; 
  225. $newHeight = ($height * $newWp) / 100; 
  226. return array('newWidth'=>intval($this->maxWidth), 'newHeight'=>intval($newHeight)); 
  227.  
  228. /** 
  229. * Calculates new image height 
  230. * @param int $width 
  231. * @param int $height 
  232. * @return array 
  233. */ 
  234. function calcHeight($width, $height) { 
  235. $newHp = (100 * $this->maxHeight) / $height; 
  236. $newWidth = ($width * $newHp) / 100; 
  237. return array('newWidth'=>intval($newWidth), 'newHeight'=>intval($this->maxHeight)); 
  238.  
  239. /** 
  240. * Calculates new image size based on percentage 
  241. * @param int $width 
  242. * @param int $height 
  243. * @return array 
  244. */ 
  245. function calcPercent($width, $height) { 
  246. $newWidth = ($width * $this->percent) / 100; 
  247. $newHeight = ($height * $this->percent) / 100; 
  248. return array('newWidth'=>intval($newWidth), 'newHeight'=>intval($newHeight)); 
  249.  
  250. /** 
  251. * Calculates new image size based on width and height, while constraining to maxWidth and maxHeight 
  252. * @param int $width 
  253. * @param int $height 
  254. */ 
  255. function calcImageSize($width, $height) { 
  256. $newSize = array('newWidth'=>$width, 'newHeight'=>$height); 
  257.  
  258. if($this->maxWidth > 0) { 
  259.  
  260. $newSize = $this->calcWidth($width, $height); 
  261.  
  262. if($this->maxHeight > 0 && $newSize['newHeight'] > $this->maxHeight) { 
  263. $newSize = $this->calcHeight($newSize['newWidth'], $newSize['newHeight']); 
  264.  
  265. //$this->newDimensions = $newSize; 
  266.  
  267. if($this->maxHeight > 0) { 
  268. $newSize = $this->calcHeight($width, $height); 
  269.  
  270. if($this->maxWidth > 0 && $newSize['newWidth'] > $this->maxWidth) { 
  271. $newSize = $this->calcWidth($newSize['newWidth'], $newSize['newHeight']); 
  272.  
  273. //$this->newDimensions = $newSize; 
  274.  
  275. $this->newDimensions = $newSize; 
  276.  
  277. /** 
  278. * Calculates new image size based percentage 
  279. * @param int $width 
  280. * @param int $height 
  281. */ 
  282. function calcImageSizePercent($width, $height) { 
  283. if($this->percent > 0) { 
  284. $this->newDimensions = $this->calcPercent($width, $height); 
  285.  
  286. /** 
  287. * Resizes image to maxWidth x maxHeight 
  288. * @param int $maxWidth 
  289. * @param int $maxHeight 
  290. */ 
  291.  
  292. function resize($maxWidth = 0, $maxHeight = 0, $resampleMode = 3) { 
  293. $this->maxWidth = $maxWidth; 
  294. $this->maxHeight = $maxHeight; 
  295.  
  296. $this->calcImageSize($this->currentDimensions['width'], $this->currentDimensions['height']); 
  297.  
  298. //string to resize the picture to $this->newDimensions['newWidth'], $this->newDimensions['newHeight'] 
  299. //should result in: -thumbnail $this->newDimensions['newWidth']x$this->newDimensions['newHeight'] 
  300. if($maxWidth=='0') 
  301. $this->imageMagickExec .= " -resize x".$maxHeight; 
  302. elseif($maxHeight=='0') 
  303. $this->imageMagickExec .= " -resize ".$maxWidth."x"; 
  304. elseif($maxHeight!='0' && $maxWidth!='0') 
  305. $this->imageMagickExec .= " -resize ".$maxWidth."x".$maxHeight; 
  306.  
  307. // next calculations should be done with the 'new' dimensions 
  308. $this->currentDimensions['width'] = $this->newDimensions['newWidth']; 
  309. $this->currentDimensions['height'] = $this->newDimensions['newHeight']; 
  310.  
  311.  
  312. /** 
  313. * Flip an image. 
  314. * @param bool $horz flip the image in horizontal mode 
  315. * @param bool $vert flip the image in vertical mode 
  316. */ 
  317. function flipImage( $horz = false, $vert = false ) { 
  318.  
  319. //TODO: need to be added 
  320.  
  321.  
  322. /** 
  323. * Rotates image either 90 degrees clockwise or counter-clockwise 
  324. * @param string $direction 
  325. */ 
  326. function rotateImage($dir = 'CW') { 
  327.  
  328. $angle = ($dir == 'CW') ? 90 : -90; 
  329.  
  330. $this->imageMagickExec .= " -rotate $angle "; 
  331.  
  332. $newWidth = $this->currentDimensions['height']; 
  333. $newHeight = $this->currentDimensions['width']; 
  334. $this->currentDimensions['width'] = $newWidth; 
  335. $this->currentDimensions['height'] = $newHeight; 
  336.  
  337. /** 
  338. * Crops the image from calculated center in a square of $cropSize pixels 
  339. * @param int $cropSize 
  340. */ 
  341. function cropFromCenter($cropSize, $resampleMode = 3) { 
  342. if($cropSize > $this->currentDimensions['width']) $cropSize = $this->currentDimensions['width']; 
  343. if($cropSize > $this->currentDimensions['height']) $cropSize = $this->currentDimensions['height']; 
  344.  
  345. //$cropX = intval(($this->currentDimensions['width'] - $cropSize) / 2); 
  346. //$cropY = intval(($this->currentDimensions['height'] - $cropSize) / 2); 
  347.  
  348. //string to crop the picture to $cropSize, $cropSize (from center) 
  349. //result: -gravity Center -crop $cropSizex$cropSize+0+0 
  350. $this->imageMagickExec .= ' -gravity Center -crop ' . $cropSize . 'x' . $cropSize . '+0+0'; 
  351.  
  352. // next calculations should be done with the 'new' dimensions 
  353. $this->currentDimensions['width'] = $cropSize; 
  354. $this->currentDimensions['height'] = $cropSize;  
  355.  
  356. /** 
  357. * Advanced cropping function that crops an image using $startX and $startY as the upper-left hand corner. 
  358. * @param int $startX 
  359. * @param int $startY 
  360. * @param int $width 
  361. * @param int $height 
  362. */ 
  363. function crop($startX, $startY, $width, $height) { 
  364. //make sure the cropped area is not greater than the size of the image 
  365. if($width > $this->currentDimensions['width']) $width = $this->currentDimensions['width']; 
  366. if($height > $this->currentDimensions['height']) $height = $this->currentDimensions['height']; 
  367. //make sure not starting outside the image 
  368. if(($startX + $width) > $this->currentDimensions['width']) $startX = ($this->currentDimensions['width'] - $width); 
  369. if(($startY + $height) > $this->currentDimensions['height']) $startY = ($this->currentDimensions['height'] - $height); 
  370. if($startX < 0) $startX = 0; 
  371. if($startY < 0) $startY = 0; 
  372.  
  373. //string to crop the picture to $width, $height (from $startX, $startY) 
  374. //result: -crop $widthx$height+$startX+$startY 
  375. $this->imageMagickExec .= ' -crop ' . $width . 'x' . $height . '+' . $startX .'+' . $startY; 
  376.  
  377. $this->currentDimensions['width'] = $width; 
  378. $this->currentDimensions['height'] = $height; 
  379.  
  380. /** 
  381. * Creates Apple-style reflection under image, optionally adding a border to main image 
  382. * @param int $percent 
  383. * @param int $reflection 
  384. * @param int $white 
  385. * @param bool $border 
  386. * @param string $borderColor 
  387. */ 
  388. function createReflection($percent, $reflection, $white, $border = true, $borderColor = '#a4a4a4') { 
  389.  
  390. $width = $this->currentDimensions['width']; 
  391. $height = $this->currentDimensions['height']; 
  392.  
  393. $reflectionHeight = intval($height * ($reflection / 100)); 
  394. $newHeight = $height + $reflectionHeight; 
  395. //$reflectedPart = $height * ((100-$percent) / 100); 
  396. $reflectedsize = intval($height * ((100 - (100 - $percent) + $reflection) / 100));  
  397.  
  398. $this->imageMagickBefore = "-size $width" . "x" ."$newHeight xc:white "; 
  399.  
  400. if($border == true) { 
  401. $this->imageMagickBefore .= " \( ";  
  402. $this->imageMagickExec = " -bordercolor '$borderColor' -border 1 \) "; 
  403.  
  404. $this->imageMagickExec .= " -geometry +0+0 -composite "; 
  405. $gradientWhite = 100-$white; 
  406. $this->imageMagickExec .= " \( '$this->fileName' -flip -resize $width"."x"."$reflectedsize\! \( -size $width"."x"."$reflectionHeight gradient: -fill black -colorize $gradientWhite \) +matte -compose copy_opacity -composite \) -geometry +0+$height -composite "; 
  407.  
  408. $this->currentDimensions['width'] = $width; 
  409. $this->currentDimensions['height'] = $newHeight; 
  410.  
  411. /** 
  412. * @param string $color 
  413. * @param string $wmFont 
  414. * @param int $wmSize 
  415. * @param int $wmOpaque 
  416. */ 
  417. function watermarkCreateText($color = '000000', $wmFont, $wmSize = 10, $wmOpaque = 90 ) { 
  418. //create a watermark.png image with the requested text. 
  419.  
  420. // set font path 
  421. $wmFontPath = NGGALLERY_ABSPATH . 'fonts/' . $wmFont; 
  422. if ( !is_readable($wmFontPath) ) 
  423. return;  
  424.  
  425. /** 
  426. $exec = "convert -size 800x500 xc:grey30 -font $wmFontPath -pointsize $wmSize -gravity center -draw \"fill '#$color$wmOpaque' text 0, 0 '$this->watermarkText'\" stamp_fgnd.png";  
  427. $make_magick = system($exec); 
  428. $exec = "convert -size 800x500 xc:black -font $wmFontPath -pointsize $wmSize -gravity center -draw \"fill white text 1, 1 '$this->watermarkText' text 0, 0 '$this->watermarkText' fill black text -1, -1 '$this->watermarkText'\" +matte stamp_mask.png"; 
  429. $make_magick = system($exec); 
  430. $exec = "composite -compose CopyOpacity stamp_mask.png stamp_fgnd.png watermark.png";*/ 
  431.  
  432. //convert the opacity between FF or 00; 100->0 and 0->FF (256) 
  433. $opacity = dechex( round( (100-$wmOpaque) * 256/100 ) ); 
  434. if ($opacity == "0") {$opacity = "00";}  
  435.  
  436. $cmd = "-size 800x500 xc:none -fill '{$color}{$opacity}' -font {$wmFontPath} -pointsize {$wmSize} -gravity center -annotate 0 '{$this->watermarkText}' watermark_text.png"; 
  437. $this->execute('convert', $cmd); 
  438.  
  439. $cmd = "-trim +repage watermark_text.png";  
  440. $this->execute('mogrify', $cmd); 
  441.  
  442. $this->watermarkImgPath = NGGALLERY_ABSPATH . 'watermark_text.png'; 
  443.  
  444. return;  
  445.  
  446. /** 
  447. * @param string $relPOS 
  448. * @param int $xPOS 
  449. * @param int $yPOS 
  450. */ 
  451. function watermarkImage( $relPOS = 'botRight', $xPOS = 0, $yPOS = 0) { 
  452.  
  453. // if it's not a valid file die...  
  454. /**if ( !is_readable($this->watermarkImgPath)) 
  455. echo $this->watermarkImgPath; 
  456. return; 
  457. } */ 
  458.  
  459. $size = GetImageSize($this->watermarkImgPath); 
  460. $watermarkDimensions = array('width'=>$size[0], 'height'=>$size[1]); 
  461.  
  462. $sourcefile_width=$this->currentDimensions['width']; 
  463. $sourcefile_height=$this->currentDimensions['height']; 
  464.  
  465. $watermarkfile_width=$watermarkDimensions['width']; 
  466. $watermarkfile_height=$watermarkDimensions['height']; 
  467.  
  468. switch( substr($relPOS, 0, 3) ) { 
  469. case 'top': $dest_y = 0 + $yPOS; break; 
  470. case 'mid': $dest_y = ($sourcefile_height / 2) - ($watermarkfile_height / 2); break; 
  471. case 'bot': $dest_y = $sourcefile_height - $watermarkfile_height - $yPOS; break; 
  472. default : $dest_y = 0; break; 
  473. switch( substr($relPOS, 3) ) { 
  474. case 'Left' : $dest_x = 0 + $xPOS; break; 
  475. case 'Center': $dest_x = ($sourcefile_width / 2) - ($watermarkfile_width / 2); break; 
  476. case 'Right': $dest_x = $sourcefile_width - $watermarkfile_width - $xPOS; break; 
  477. default : $dest_x = 0; break; 
  478. if ($dest_y<0) { 
  479. $dest_y = $dest_y;  
  480. } else {  
  481. $dest_y = '+' . $dest_y; 
  482. if ($dest_x<0) { 
  483. $dest_x = $dest_x;  
  484. } else {  
  485. $dest_x = '+' . $dest_x; 
  486.  
  487. $this->imageMagickComp .= "'$this->watermarkImgPath' -geometry $dest_x$dest_y -composite"; 
  488. //" -dissolve 80% -geometry +$dest_x+$dest_y $this->watermarkImgPath"; 
  489.  
  490. /** 
  491. * Saves image as $name (can include file path), with quality of # percent if file is a jpeg 
  492. * @param string $name 
  493. * @param int $quality 
  494. * @return bool errorstate 
  495. */ 
  496. function save( $name, $quality = 85 ) { 
  497. $this->show($quality, $name); 
  498. if ($this->error == true) { 
  499. //$this->errmsg = 'Create Image failed. Check safe mode settings'; 
  500. return false; 
  501.  
  502. if( function_exists('do_action') ) 
  503. do_action('ngg_ajax_image_save', $name); 
  504.  
  505. return true; 
  506.  
  507. /** 
  508. * Outputs the image to the screen, or saves to $name if supplied. Quality of JPEG images can be controlled with the $quality variable 
  509. * @param int $quality 
  510. * @param string $name 
  511. */ 
  512. function show( $quality = 85, $name = '') { 
  513. //save the image if we get a filename 
  514. if( $name != '' ) { 
  515. $args = "{$this->imageMagickBefore} "; 
  516. $args .= escapeshellarg("$this->fileName"); 
  517. $args .= " $this->imageMagickExec $this->imageMagickComp -quality '$quality' "; 
  518. $args .= escapeshellarg("$name"); 
  519. //$args = "{$this->imageMagickBefore} '$this->fileName' $this->imageMagickExec $this->imageMagickComp -quality $quality '$name'"; 
  520. $this->execute('convert', $args); 
  521. //$this->error = true;  
  522. } else { 
  523. //return a raw image stream 
  524. $args = "{$this->imageMagickBefore} '$this->fileName' $this->imageMagickExec $this->imageMagickComp -quality $quality JPG:-";  
  525. $this->execute('convert', $args, true); 
  526. $this->error = true; 
/lib/gd.thumbnail.inc.php  
  1. class ngg_Thumbnail { 
  2. /** 
  3. * Error message to display, if any 
  4. * @var string 
  5. */ 
  6. var $errmsg; 
  7. /** 
  8. * Whether or not there is an error 
  9. * @var boolean 
  10. */ 
  11. var $error; 
  12. /** 
  13. * Format of the image file 
  14. * @var string 
  15. */ 
  16. var $format; 
  17. /** 
  18. * File name and path of the image file 
  19. * @var string 
  20. */ 
  21. var $fileName; 
  22. /** 
  23. * Current dimensions of working image 
  24. * @var array 
  25. */ 
  26. var $currentDimensions; 
  27. /** 
  28. * New dimensions of working image 
  29. * @var array 
  30. */ 
  31. var $newDimensions; 
  32. /** 
  33. * Image resource for newly manipulated image 
  34. * @var resource 
  35. * @access private 
  36. */ 
  37. var $newImage; 
  38. /** 
  39. * Image resource for image before previous manipulation 
  40. * @var resource 
  41. * @access private 
  42. */ 
  43. var $oldImage; 
  44. /** 
  45. * Image resource for image being currently manipulated 
  46. * @var resource 
  47. * @access private 
  48. */ 
  49. var $workingImage; 
  50. /** 
  51. * Percentage to resize image by 
  52. * @var int 
  53. * @access private 
  54. */ 
  55. var $percent; 
  56. /** 
  57. * Maximum width of image during resize 
  58. * @var int 
  59. * @access private 
  60. */ 
  61. var $maxWidth; 
  62. /** 
  63. * Maximum height of image during resize 
  64. * @var int 
  65. * @access private 
  66. */ 
  67. var $maxHeight; 
  68. /** 
  69. * Image for Watermark 
  70. * @var string 
  71. *  
  72. */ 
  73. var $watermarkImgPath; 
  74. /** 
  75. * Text for Watermark 
  76. * @var string 
  77. *  
  78. */ 
  79. var $watermarkText; 
  80. /** 
  81. * Image Resource ID for Watermark 
  82. * @var string 
  83. *  
  84. */ 
  85. function ngg_Thumbnail($fileName, $no_ErrorImage = false) { 
  86. //make sure the GD library is installed 
  87. if(!function_exists("gd_info")) { 
  88. echo 'You do not have the GD Library installed. This class requires the GD library to function properly.' . "\n"; 
  89. echo 'visit http://us2.php.net/manual/en/ref.image.php for more information'; 
  90. exit; 
  91. //initialize variables 
  92. $this->errmsg = ''; 
  93. $this->error = false; 
  94. $this->currentDimensions = array(); 
  95. $this->newDimensions = array(); 
  96. $this->fileName = $fileName; 
  97. $this->percent = 100; 
  98. $this->maxWidth = 0; 
  99. $this->maxHeight = 0; 
  100. $this->watermarkImgPath = ''; 
  101. $this->watermarkText = ''; 
  102.  
  103. //check to see if file exists 
  104. if(!file_exists($this->fileName)) { 
  105. $this->errmsg = 'File not found'; 
  106. $this->error = true; 
  107. //check to see if file is readable 
  108. elseif(!is_readable($this->fileName)) { 
  109. $this->errmsg = 'File is not readable'; 
  110. $this->error = true; 
  111.  
  112. //if there are no errors, determine the file format 
  113. if($this->error == false) { 
  114. $data = @getimagesize($this->fileName); 
  115. if (isset($data) && is_array($data)) { 
  116. $extensions = array('1' => 'GIF', '2' => 'JPG', '3' => 'PNG'); 
  117. $extension = array_key_exists($data[2], $extensions) ? $extensions[$data[2]] : ''; 
  118. if($extension) { 
  119. $this->format = $extension; 
  120. } else { 
  121. $this->errmsg = 'Unknown file format'; 
  122. $this->error = true; 
  123. } else { 
  124. $this->errmsg = 'File is not an image'; 
  125. $this->error = true; 
  126.  
  127. // increase memory-limit if possible, GD needs this for large images 
  128. // @ini_set('memory_limit', '128M'); 
  129.  
  130. if($this->error == false) {  
  131. // Check memory consumption if file exists 
  132. $this->checkMemoryForImage($this->fileName); 
  133.  
  134. //initialize resources if no errors 
  135. if($this->error == false) {  
  136.  
  137. switch($this->format) {  
  138. case 'GIF': 
  139. $this->oldImage = ImageCreateFromGif($this->fileName); 
  140. break; 
  141. case 'JPG': 
  142. $this->oldImage = ImageCreateFromJpeg($this->fileName); 
  143. break; 
  144. case 'PNG': 
  145. $this->oldImage = ImageCreateFromPng($this->fileName); 
  146. break; 
  147. if (!$this->oldImage) {  
  148. $this->errmsg = 'Create Image failed. Check memory limit'; 
  149. $this->error = true; 
  150. } else { 
  151. $size = GetImageSize($this->fileName); 
  152. $this->currentDimensions = array('width'=>$size[0], 'height'=>$size[1]); 
  153. $this->newImage = $this->oldImage; 
  154.  
  155.  
  156. if($this->error == true) { 
  157. if(!$no_ErrorImage) 
  158. $this->showErrorImage(); 
  159. return; 
  160.  
  161. /** 
  162. * Calculate the memory limit 
  163. */ 
  164. function checkMemoryForImage( $filename ) { 
  165.  
  166. if ( (function_exists('memory_get_usage')) && (ini_get('memory_limit')) ) { 
  167. $imageInfo = getimagesize($filename); 
  168. switch($this->format) {  
  169. case 'GIF': 
  170. // measured factor 1 is better 
  171. $CHANNEL = 1; 
  172. break; 
  173. case 'JPG': 
  174. $CHANNEL = $imageInfo['channels']; 
  175. break; 
  176. case 'PNG': 
  177. // didn't get the channel for png 
  178. $CHANNEL = 3; 
  179. break; 
  180. $MB = 1048576; // number of bytes in 1M 
  181. $K64 = 65536; // number of bytes in 64K 
  182. $TWEAKFACTOR = 1.68; // Or whatever works for you 
  183. $memoryNeeded = round( ( $imageInfo[0] * $imageInfo[1] 
  184. * $imageInfo['bits'] 
  185. * $CHANNEL / 8 
  186. + $K64 
  187. ) * $TWEAKFACTOR 
  188. ); 
  189. $memoryNeeded = memory_get_usage() + $memoryNeeded; 
  190. // get memory limit 
  191. $memory_limit = ini_get('memory_limit'); 
  192.  
  193. // PHP docs : Note that to have no memory limit, set this directive to -1. 
  194. if ($memory_limit == -1 ) return; 
  195.  
  196. // Just check megabyte limits, not higher 
  197. if ( strtolower(substr($memory_limit, -1)) == 'm' ) { 
  198.  
  199. if ($memory_limit != '') { 
  200. $memory_limit = substr($memory_limit, 0, -1) * 1024 * 1024; 
  201.  
  202. if ($memoryNeeded > $memory_limit) { 
  203. $memoryNeeded = round ($memoryNeeded / 1024 / 1024, 2); 
  204. $this->errmsg = 'Exceed Memory limit. Require : '.$memoryNeeded. " MByte" ; 
  205. $this->error = true; 
  206. return; 
  207.  
  208. /** 
  209. * Must be called to free up allocated memory after all manipulations are done 
  210. */ 
  211. function destruct() { 
  212. if(is_resource($this->newImage)) @ImageDestroy($this->newImage); 
  213. if(is_resource($this->oldImage)) @ImageDestroy($this->oldImage); 
  214. if(is_resource($this->workingImage)) @ImageDestroy($this->workingImage); 
  215.  
  216. /** 
  217. * Returns the current width of the image 
  218. * @return int 
  219. */ 
  220. function getCurrentWidth() { 
  221. return $this->currentDimensions['width']; 
  222.  
  223. /** 
  224. * Returns the current height of the image 
  225. * @return int 
  226. */ 
  227. function getCurrentHeight() { 
  228. return $this->currentDimensions['height']; 
  229.  
  230. /** 
  231. * Calculates new image width 
  232. * @param int $width 
  233. * @param int $height 
  234. * @return array 
  235. */ 
  236. function calcWidth($width, $height) { 
  237. $newWp = (100 * $this->maxWidth) / $width; 
  238. $newHeight = ($height * $newWp) / 100; 
  239. return array('newWidth'=>intval($this->maxWidth), 'newHeight'=>intval($newHeight)); 
  240.  
  241. /** 
  242. * Calculates new image height 
  243. * @param int $width 
  244. * @param int $height 
  245. * @return array 
  246. */ 
  247. function calcHeight($width, $height) { 
  248. $newHp = (100 * $this->maxHeight) / $height; 
  249. $newWidth = ($width * $newHp) / 100; 
  250. return array('newWidth'=>intval($newWidth), 'newHeight'=>intval($this->maxHeight)); 
  251.  
  252. /** 
  253. * Calculates new image size based on percentage 
  254. * @param int $width 
  255. * @param int $height 
  256. * @return array 
  257. */ 
  258. function calcPercent($width, $height) { 
  259. $newWidth = ($width * $this->percent) / 100; 
  260. $newHeight = ($height * $this->percent) / 100; 
  261. return array('newWidth'=>intval($newWidth), 'newHeight'=>intval($newHeight)); 
  262.  
  263. /** 
  264. * Calculates new image size based on width and height, while constraining to maxWidth and maxHeight 
  265. * @param int $width 
  266. * @param int $height 
  267. */ 
  268. function calcImageSize($width, $height) { 
  269. $newSize = array('newWidth'=>$width, 'newHeight'=>$height); 
  270.  
  271. if($this->maxWidth > 0) { 
  272.  
  273. $newSize = $this->calcWidth($width, $height); 
  274.  
  275. if($this->maxHeight > 0 && $newSize['newHeight'] > $this->maxHeight) { 
  276. $newSize = $this->calcHeight($newSize['newWidth'], $newSize['newHeight']); 
  277.  
  278. //$this->newDimensions = $newSize; 
  279.  
  280. if($this->maxHeight > 0) { 
  281. $newSize = $this->calcHeight($width, $height); 
  282.  
  283. if($this->maxWidth > 0 && $newSize['newWidth'] > $this->maxWidth) { 
  284. $newSize = $this->calcWidth($newSize['newWidth'], $newSize['newHeight']); 
  285.  
  286. //$this->newDimensions = $newSize; 
  287.  
  288. $this->newDimensions = $newSize; 
  289.  
  290. /** 
  291. * Calculates new image size based percentage 
  292. * @param int $width 
  293. * @param int $height 
  294. */ 
  295. function calcImageSizePercent($width, $height) { 
  296. if($this->percent > 0) { 
  297. $this->newDimensions = $this->calcPercent($width, $height); 
  298.  
  299. /** 
  300. * Displays error image 
  301. */ 
  302. function showErrorImage() { 
  303. header('Content-type: image/png'); 
  304. $errImg = ImageCreate(220, 25); 
  305. $bgColor = imagecolorallocate($errImg, 0, 0, 0); 
  306. $fgColor1 = imagecolorallocate($errImg, 255, 255, 255); 
  307. $fgColor2 = imagecolorallocate($errImg, 255, 0, 0); 
  308. imagestring($errImg, 3, 6, 6, 'Error:', $fgColor2); 
  309. imagestring($errImg, 3, 55, 6, $this->errmsg, $fgColor1); 
  310. imagepng($errImg); 
  311. imagedestroy($errImg); 
  312.  
  313. /** 
  314. * Resizes image to fixed Width x Height 
  315. *  
  316. * @param int $Width 
  317. * @param int $Height 
  318. */ 
  319. function resizeFix($Width = 0, $Height = 0, $deprecated = 3) { 
  320. $this->newWidth = $Width; 
  321. $this->newHeight = $Height; 
  322.  
  323. if(function_exists("ImageCreateTrueColor")) { 
  324. $this->workingImage = ImageCreateTrueColor($this->newWidth, $this->newHeight); 
  325. else { 
  326. $this->workingImage = ImageCreate($this->newWidth, $this->newHeight); 
  327.  
  328. // ImageCopyResampled( 
  329. $this->imagecopyresampled( 
  330. $this->workingImage,  
  331. $this->oldImage,  
  332. 0,  
  333. 0,  
  334. 0,  
  335. 0,  
  336. $this->newWidth,  
  337. $this->newHeight,  
  338. $this->currentDimensions['width'],  
  339. $this->currentDimensions['height'] 
  340. ); 
  341.  
  342. $this->oldImage = $this->workingImage; 
  343. $this->newImage = $this->workingImage; 
  344. $this->currentDimensions['width'] = $this->newWidth; 
  345. $this->currentDimensions['height'] = $this->newHeight; 
  346.  
  347.  
  348. /** 
  349. * Resizes image to maxWidth x maxHeight 
  350. * @param int $maxWidth 
  351. * @param int $maxHeight 
  352. */ 
  353. function resize($maxWidth = 0, $maxHeight = 0, $deprecated = 3) { 
  354. $this->maxWidth = $maxWidth; 
  355. $this->maxHeight = $maxHeight; 
  356.  
  357. $this->calcImageSize($this->currentDimensions['width'], $this->currentDimensions['height']); 
  358.  
  359. if(function_exists("ImageCreateTrueColor")) { 
  360. $this->workingImage = ImageCreateTrueColor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); 
  361. else { 
  362. $this->workingImage = ImageCreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); 
  363.  
  364. // ImageCopyResampled( 
  365. $this->imagecopyresampled( 
  366. $this->workingImage,  
  367. $this->oldImage,  
  368. 0,  
  369. 0,  
  370. 0,  
  371. 0,  
  372. $this->newDimensions['newWidth'],  
  373. $this->newDimensions['newHeight'],  
  374. $this->currentDimensions['width'],  
  375. $this->currentDimensions['height'] 
  376. ); 
  377.  
  378. $this->oldImage = $this->workingImage; 
  379. $this->newImage = $this->workingImage; 
  380. $this->currentDimensions['width'] = $this->newDimensions['newWidth']; 
  381. $this->currentDimensions['height'] = $this->newDimensions['newHeight']; 
  382.  
  383. /** 
  384. * Resizes the image by $percent percent 
  385. * @param int $percent 
  386. */ 
  387. function resizePercent($percent = 0) { 
  388. $this->percent = $percent; 
  389.  
  390. $this->calcImageSizePercent($this->currentDimensions['width'], $this->currentDimensions['height']); 
  391.  
  392. if(function_exists("ImageCreateTrueColor")) { 
  393. $this->workingImage = ImageCreateTrueColor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); 
  394. else { 
  395. $this->workingImage = ImageCreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); 
  396.  
  397. $this->ImageCopyResampled( 
  398. $this->workingImage,  
  399. $this->oldImage,  
  400. 0,  
  401. 0,  
  402. 0,  
  403. 0,  
  404. $this->newDimensions['newWidth'],  
  405. $this->newDimensions['newHeight'],  
  406. $this->currentDimensions['width'],  
  407. $this->currentDimensions['height'] 
  408. ); 
  409.  
  410. $this->oldImage = $this->workingImage; 
  411. $this->newImage = $this->workingImage; 
  412. $this->currentDimensions['width'] = $this->newDimensions['newWidth']; 
  413. $this->currentDimensions['height'] = $this->newDimensions['newHeight']; 
  414.  
  415. /** 
  416. * Crops the image from calculated center in a square of $cropSize pixels 
  417. * @param int $cropSize 
  418. */ 
  419. function cropFromCenter($cropSize) { 
  420. if($cropSize > $this->currentDimensions['width']) $cropSize = $this->currentDimensions['width']; 
  421. if($cropSize > $this->currentDimensions['height']) $cropSize = $this->currentDimensions['height']; 
  422.  
  423. $cropX = intval(($this->currentDimensions['width'] - $cropSize) / 2); 
  424. $cropY = intval(($this->currentDimensions['height'] - $cropSize) / 2); 
  425.  
  426. if(function_exists("ImageCreateTrueColor")) { 
  427. $this->workingImage = ImageCreateTrueColor($cropSize, $cropSize); 
  428. else { 
  429. $this->workingImage = ImageCreate($cropSize, $cropSize); 
  430.  
  431. $this->imagecopyresampled( 
  432. $this->workingImage,  
  433. $this->oldImage,  
  434. 0,  
  435. 0,  
  436. $cropX,  
  437. $cropY,  
  438. $cropSize,  
  439. $cropSize,  
  440. $cropSize,  
  441. $cropSize 
  442. ); 
  443.  
  444. $this->oldImage = $this->workingImage; 
  445. $this->newImage = $this->workingImage; 
  446. $this->currentDimensions['width'] = $cropSize; 
  447. $this->currentDimensions['height'] = $cropSize; 
  448.  
  449. /** 
  450. * Advanced cropping function that crops an image using $startX and $startY as the upper-left hand corner. 
  451. * @param int $startX 
  452. * @param int $startY 
  453. * @param int $width 
  454. * @param int $height 
  455. */ 
  456. function crop($startX, $startY, $width, $height) { 
  457. //make sure the cropped area is not greater than the size of the image 
  458. if($width > $this->currentDimensions['width']) $width = $this->currentDimensions['width']; 
  459. if($height > $this->currentDimensions['height']) $height = $this->currentDimensions['height']; 
  460. //make sure not starting outside the image 
  461. if(($startX + $width) > $this->currentDimensions['width']) $startX = ($this->currentDimensions['width'] - $width); 
  462. if(($startY + $height) > $this->currentDimensions['height']) $startY = ($this->currentDimensions['height'] - $height); 
  463. if($startX < 0) $startX = 0; 
  464. if($startY < 0) $startY = 0; 
  465.  
  466. if(function_exists("ImageCreateTrueColor")) { 
  467. $this->workingImage = ImageCreateTrueColor($width, $height); 
  468. else { 
  469. $this->workingImage = ImageCreate($width, $height); 
  470.  
  471. $this->imagecopyresampled( 
  472. $this->workingImage,  
  473. $this->oldImage,  
  474. 0,  
  475. 0,  
  476. $startX,  
  477. $startY,  
  478. $width,  
  479. $height,  
  480. $width,  
  481. $height 
  482. ); 
  483.  
  484. $this->oldImage = $this->workingImage; 
  485. $this->newImage = $this->workingImage; 
  486. $this->currentDimensions['width'] = $width; 
  487. $this->currentDimensions['height'] = $height; 
  488.  
  489. /** 
  490. * Outputs the image to the screen, or saves to $name if supplied. Quality of JPEG images can be controlled with the $quality variable 
  491. * @param int $quality 
  492. * @param string $name 
  493. */ 
  494. function show($quality=100, $name = '') { 
  495. switch($this->format) { 
  496. case 'GIF': 
  497. if($name != '') { 
  498. @ImageGif($this->newImage, $name) or $this->error = true; 
  499. else { 
  500. header('Content-type: image/gif'); 
  501. ImageGif($this->newImage); 
  502. break; 
  503. case 'JPG': 
  504. if($name != '') { 
  505. @ImageJpeg($this->newImage, $name, $quality) or $this->error = true; 
  506. else { 
  507. header('Content-type: image/jpeg'); 
  508. ImageJpeg($this->newImage, NULL, $quality); 
  509. break; 
  510. case 'PNG': 
  511. if($name != '') { 
  512. @ImagePng($this->newImage, $name) or $this->error = true; 
  513. else { 
  514. header('Content-type: image/png'); 
  515. ImagePng($this->newImage); 
  516. break; 
  517.  
  518. /** 
  519. * Saves image as $name (can include file path), with quality of # percent if file is a jpeg 
  520. * @param string $name 
  521. * @param int $quality 
  522. * @return bool errorstate 
  523. */ 
  524. function save($name, $quality=100) { 
  525. $this->show($quality, $name); 
  526. if ($this->error == true) { 
  527. $this->errmsg = 'Create Image failed. Check safe mode settings'; 
  528. return false; 
  529.  
  530. if( function_exists('do_action') ) 
  531. do_action('ngg_ajax_image_save', $name); 
  532.  
  533. return true; 
  534.  
  535. /** 
  536. * Creates Apple-style reflection under image, optionally adding a border to main image 
  537. * @param int $percent 
  538. * @param int $reflection 
  539. * @param int $white 
  540. * @param bool $border 
  541. * @param string $borderColor 
  542. */ 
  543. function createReflection($percent, $reflection, $white, $border = true, $borderColor = '#a4a4a4') { 
  544. $width = $this->currentDimensions['width']; 
  545. $height = $this->currentDimensions['height']; 
  546.  
  547. $reflectionHeight = intval($height * ($reflection / 100)); 
  548. $newHeight = $height + $reflectionHeight; 
  549. $reflectedPart = $height * ($percent / 100); 
  550.  
  551. $this->workingImage = ImageCreateTrueColor($width, $newHeight); 
  552.  
  553. ImageAlphaBlending($this->workingImage, true); 
  554.  
  555. $colorToPaint = ImageColorAllocateAlpha($this->workingImage, 255, 255, 255, 0); 
  556. ImageFilledRectangle($this->workingImage, 0, 0, $width, $newHeight, $colorToPaint); 
  557.  
  558. imagecopyresampled( 
  559. $this->workingImage,  
  560. $this->newImage,  
  561. 0,  
  562. 0,  
  563. 0,  
  564. $reflectedPart,  
  565. $width,  
  566. $reflectionHeight,  
  567. $width,  
  568. ($height - $reflectedPart)); 
  569. $this->imageFlipVertical(); 
  570.  
  571. imagecopy($this->workingImage, $this->newImage, 0, 0, 0, 0, $width, $height); 
  572.  
  573. imagealphablending($this->workingImage, true); 
  574.  
  575. for($i=0;$i<$reflectionHeight;$i++) { 
  576. $colorToPaint = imagecolorallocatealpha($this->workingImage, 255, 255, 255, ($i/$reflectionHeight*-1+1)*$white); 
  577. imagefilledrectangle($this->workingImage, 0, $height+$i, $width, $height+$i, $colorToPaint); 
  578.  
  579. if($border == true) { 
  580. $rgb = $this->hex2rgb($borderColor, false); 
  581. $colorToPaint = imagecolorallocate($this->workingImage, $rgb[0], $rgb[1], $rgb[2]); 
  582. imageline($this->workingImage, 0, 0, $width, 0, $colorToPaint); //top line 
  583. imageline($this->workingImage, 0, $height, $width, $height, $colorToPaint); //bottom line 
  584. imageline($this->workingImage, 0, 0, 0, $height, $colorToPaint); //left line 
  585. imageline($this->workingImage, $width-1, 0, $width-1, $height, $colorToPaint); //right line 
  586.  
  587. $this->oldImage = $this->workingImage; 
  588. $this->newImage = $this->workingImage; 
  589. $this->currentDimensions['width'] = $width; 
  590. $this->currentDimensions['height'] = $newHeight; 
  591.  
  592. /** 
  593. * Flip an image. 
  594. * @param bool $horz flip the image in horizontal mode 
  595. * @param bool $vert flip the image in vertical mode 
  596. */ 
  597. function flipImage( $horz = false, $vert = false ) { 
  598.  
  599. $sx = $vert ? ($this->currentDimensions['width'] - 1) : 0; 
  600. $sy = $horz ? ($this->currentDimensions['height'] - 1) : 0; 
  601. $sw = $vert ? -$this->currentDimensions['width'] : $this->currentDimensions['width']; 
  602. $sh = $horz ? -$this->currentDimensions['height'] : $this->currentDimensions['height']; 
  603.  
  604. $this->workingImage = imagecreatetruecolor( $this->currentDimensions['width'], $this->currentDimensions['height'] );  
  605.  
  606. $this->imagecopyresampled($this->workingImage, $this->oldImage, 0, 0, $sx, $sy, $this->currentDimensions['width'], $this->currentDimensions['height'], $sw, $sh) ; 
  607. $this->oldImage = $this->workingImage; 
  608. $this->newImage = $this->workingImage; 
  609.  
  610. return true; 
  611.  
  612. /** 
  613. * Rotate an image clockwise or counter clockwise 
  614. * @param string $direction could be CW or CCW 
  615. */ 
  616. function rotateImage( $dir = 'CW' ) { 
  617.  
  618. $angle = ($dir == 'CW') ? 90 : -90; 
  619.  
  620. if ( function_exists('imagerotate') ) { 
  621. $transparency = imagecolorallocatealpha($this->oldImage, 255, 255, 255, 127); 
  622. $this->workingImage = imagerotate($this->oldImage, 360 - $angle, $transparency); // imagerotate() rotates CCW 
  623. imagealphablending($this->workingImage, true); 
  624. imagesavealpha($this->workingImage, true); 
  625. $this->currentDimensions['width'] = imagesx($this->workingImage); 
  626. $this->currentDimensions['height'] = imagesy($this->workingImage); 
  627. $this->oldImage = $this->workingImage; 
  628. $this->newImage = $this->workingImage; 
  629. return true; 
  630.  
  631. $this->workingImage = imagecreatetruecolor( $this->currentDimensions['height'], $this->currentDimensions['width'] );  
  632.  
  633. imagealphablending($this->workingImage, false);  
  634. imagesavealpha($this->workingImage, true);  
  635.  
  636. switch ($angle) { 
  637.  
  638. case 90 : 
  639. for( $x = 0; $x < $this->currentDimensions['width']; $x++ ) {  
  640. for( $y = 0; $y < $this->currentDimensions['height']; $y++ ) {  
  641. if ( !imagecopy($this->workingImage, $this->oldImage, $this->currentDimensions['height'] - $y - 1, $x, $x, $y, 1, 1) )  
  642. return false;  
  643. }  
  644. }  
  645. break; 
  646.  
  647. case -90 : 
  648. for( $x = 0; $x < $this->currentDimensions['width']; $x++ ) {  
  649. for( $y = 0; $y < $this->currentDimensions['height']; $y++ ) {  
  650. if ( !imagecopy($this->workingImage, $this->oldImage, $y, $this->currentDimensions['width'] - $x - 1, $x, $y, 1, 1) )  
  651. return false;  
  652. }  
  653. }  
  654. break; 
  655.  
  656. default :  
  657. return false; 
  658.  
  659. $this->currentDimensions['width'] = imagesx($this->workingImage); 
  660. $this->currentDimensions['height'] = imagesy($this->workingImage);  
  661. $this->oldImage = $this->workingImage; 
  662. $this->newImage = $this->workingImage; 
  663.  
  664. return true; 
  665.  
  666. }  
  667.  
  668. /** 
  669. * Inverts working image, used by reflection function 
  670. *  
  671. * @access private 
  672. */ 
  673. function imageFlipVertical() { 
  674. $x_i = imagesx($this->workingImage); 
  675. $y_i = imagesy($this->workingImage); 
  676.  
  677. for($x = 0; $x < $x_i; $x++) { 
  678. for($y = 0; $y < $y_i; $y++) { 
  679. imagecopy($this->workingImage, $this->workingImage, $x, $y_i - $y - 1, $x, $y, 1, 1); 
  680.  
  681. /** 
  682. * Converts hexidecimal color value to rgb values and returns as array/string 
  683. * @param string $hex 
  684. * @param bool $asString 
  685. * @return array|string 
  686. */ 
  687. function hex2rgb($hex, $asString = false) { 
  688. // strip off any leading # 
  689. if (0 === strpos($hex, '#')) { 
  690. $hex = substr($hex, 1); 
  691. } else if (0 === strpos($hex, '&H')) { 
  692. $hex = substr($hex, 2); 
  693.  
  694. // break into hex 3-tuple 
  695. $cutpoint = ceil(strlen($hex) / 2)-1; 
  696. $rgb = explode(':', wordwrap($hex, $cutpoint, ':', $cutpoint), 3); 
  697.  
  698. // convert each tuple to decimal 
  699. $rgb[0] = (isset($rgb[0]) ? hexdec($rgb[0]) : 0); 
  700. $rgb[1] = (isset($rgb[1]) ? hexdec($rgb[1]) : 0); 
  701. $rgb[2] = (isset($rgb[2]) ? hexdec($rgb[2]) : 0); 
  702.  
  703. return ($asString ? "{$rgb[0]} {$rgb[1]} {$rgb[2]}" : $rgb); 
  704.  
  705. /** 
  706. * Based on the Watermark function by Marek Malcherek  
  707. * http://www.malcherek.de 
  708. * @param string $color 
  709. * @param string $wmFont 
  710. * @param int $wmSize 
  711. * @param int $wmOpaque 
  712. */ 
  713. function watermarkCreateText($color = '000000', $wmFont, $wmSize = 10, $wmOpaque = 90 ) { 
  714. // set font path 
  715. $wmFontPath = NGGALLERY_ABSPATH."fonts/".$wmFont; 
  716. if ( !is_readable($wmFontPath)) 
  717. return;  
  718.  
  719. // This function requires both the GD library and the FreeType library.  
  720. if ( !function_exists('ImageTTFBBox') ) 
  721. return; 
  722.  
  723. $TextSize = @ImageTTFBBox($wmSize, 0, $wmFontPath, $this->watermarkText) or die; 
  724. $TextWidth = abs($TextSize[2]) + abs($TextSize[0]); 
  725. $TextHeight = abs($TextSize[7]) + abs($TextSize[1]); 
  726. // Create Image for Text 
  727. $this->workingImage = ImageCreateTrueColor($TextWidth, $TextHeight); 
  728. ImageSaveAlpha($this->workingImage, true); 
  729. ImageAlphaBlending($this->workingImage, false); 
  730. $bgText = imagecolorallocatealpha($this->workingImage, 255, 255, 255, 127); 
  731. imagefill($this->workingImage, 0, 0, $bgText); 
  732. $wmTransp = 127 -( $wmOpaque * 1.27 ); 
  733. $rgb = $this->hex2rgb($color, false); 
  734. $TextColor = imagecolorallocatealpha($this->workingImage, $rgb[0], $rgb[1], $rgb[2], $wmTransp); 
  735.  
  736. // Create Text on image 
  737. imagettftext($this->workingImage, $wmSize, 0, 0, abs($TextSize[5]), $TextColor, $wmFontPath, $this->watermarkText); 
  738. $this->watermarkImgPath = $this->workingImage; 
  739.  
  740. return;  
  741.  
  742. /** 
  743. * Modfied Watermark function by Steve Peart  
  744. * http://parasitehosting.com/ 
  745. * @param string $relPOS 
  746. * @param int $xPOS 
  747. * @param int $yPOS 
  748. */ 
  749. function watermarkImage( $relPOS = 'botRight', $xPOS = 0, $yPOS = 0) { 
  750.  
  751. // if it's a resource ID take it as watermark text image 
  752. if(is_resource($this->watermarkImgPath)) { 
  753. $this->workingImage = $this->watermarkImgPath; 
  754. } else { 
  755. // Would you really want to use anything other than a png?  
  756. $this->workingImage = @imagecreatefrompng($this->watermarkImgPath); 
  757. // if it's not a valid file die... 
  758. if (empty($this->workingImage) or (!$this->workingImage)) 
  759. return; 
  760.  
  761. imagealphablending($this->workingImage, false); 
  762. imagesavealpha($this->workingImage, true); 
  763. $sourcefile_width=imageSX($this->oldImage); 
  764. $sourcefile_height=imageSY($this->oldImage); 
  765. $watermarkfile_width=imageSX($this->workingImage); 
  766. $watermarkfile_height=imageSY($this->workingImage); 
  767. switch(substr($relPOS, 0, 3)) { 
  768. case 'top': $dest_y = 0 + $yPOS; break; 
  769. case 'mid': $dest_y = ($sourcefile_height / 2) - ($watermarkfile_height / 2); break; 
  770. case 'bot': $dest_y = $sourcefile_height - $watermarkfile_height - $yPOS; break; 
  771. default : $dest_y = 0; break; 
  772. switch(substr($relPOS, 3)) { 
  773. case 'Left' : $dest_x = 0 + $xPOS; break; 
  774. case 'Center': $dest_x = ($sourcefile_width / 2) - ($watermarkfile_width / 2); break; 
  775. case 'Right': $dest_x = $sourcefile_width - $watermarkfile_width - $xPOS; break; 
  776. default : $dest_x = 0; break; 
  777.  
  778. // debug  
  779. // $this->errmsg = 'X '.$dest_x.' Y '.$dest_y; 
  780. // $this->showErrorImage(); 
  781.  
  782. // if a gif, we have to upsample it to a truecolor image 
  783. if($this->format == 'GIF') { 
  784. $tempimage = imagecreatetruecolor($sourcefile_width, $sourcefile_height); 
  785. imagecopy($tempimage, $this->oldImage, 0, 0, 0, 0, $sourcefile_width, $sourcefile_height); 
  786. $this->newImage = $tempimage; 
  787.  
  788. imagecopy($this->newImage, $this->workingImage, $dest_x, $dest_y, 0, 0, $watermarkfile_width, $watermarkfile_height); 
  789.  
  790. /** 
  791. * Modfied imagecopyresampled function to save transparent images 
  792. * See : http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/ 
  793. * @since 1.9.0 
  794. *  
  795. * @param resource $dst_image 
  796. * @param resource $src_image 
  797. * @param int $dst_x 
  798. * @param int $dst_y 
  799. * @param int $src_x 
  800. * @param int $src_y 
  801. * @param int $dst_w 
  802. * @param int $dst_h 
  803. * @param int $src_w 
  804. * @param int $src_h 
  805. * @return bool 
  806. */ 
  807. function imagecopyresampled( &$dst_image , $src_image , $dst_x , $dst_y , $src_x , $src_y , $dst_w , $dst_h , $src_w , $src_h) { 
  808.  
  809. // Check if this image is PNG or GIF, then set if Transparent  
  810. if( $this->format == 'GIF' || $this->format == 'PNG') { 
  811. imagealphablending($dst_image, false); 
  812. imagesavealpha($dst_image, true); 
  813. $transparent = imagecolorallocatealpha($dst_image, 255, 255, 255, 127); 
  814. imagefilledrectangle($dst_image, 0, 0, $dst_w, $dst_h, $transparent); 
  815.  
  816. imagecopyresampled($dst_image , $src_image , $dst_x , $dst_y , $src_x , $src_y , $dst_w , $dst_h , $src_w , $src_h); 
  817. return true;