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).

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