Guest User

Untitled

a guest
Jun 27th, 2010
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.02 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * Library for image handling using the Imagick library of functions
  5. *
  6. * @package core
  7. */
  8.  
  9. // force UTF-8 Ø
  10.  
  11. // Suggested ImageMagick v6.3.8
  12. $_imagick_present = extension_loaded('imagick');
  13. $_imagick_version = version_compare(phpversion('imagick'), '2.1.0', '>=');
  14. $_zp_imagick_present = $_imagick_present && $_imagick_version;
  15.  
  16. $_zp_graphics_optionhandlers[] = new lib_Imagick_Options();
  17.  
  18. /**
  19. * Option class for lib-Imagick
  20. */
  21. class lib_Imagick_Options {
  22.  
  23. /**
  24. * Standard option interface
  25. *
  26. * @return array
  27. */
  28. function getOptionsSupported() {
  29. global $_zp_imagick_present;
  30. if ($_zp_imagick_present) {
  31. if (!sanitize_numeric(getOption('magick_font_size'))) {
  32. setOption('magick_font_size', 18);
  33. }
  34.  
  35. $mem_lim = getOption('magick_mem_lim');
  36. if (!is_numeric($mem_lim) || $mem_lim < 0 ) {
  37. setOption('magick_mem_lim', 0);
  38. }
  39.  
  40. return array( gettext('Enable Imagick') => array( 'key' => 'use_Imagick',
  41. 'type' => OPTION_TYPE_CHECKBOX,
  42. 'order' => 0,
  43. 'desc' => gettext('Your PHP has support for Imagick. Check this option if you wish to use the Imagick graphics library.')),
  44. gettext('Imagick memory limit') => array( 'key' => 'magick_mem_lim',
  45. 'type' => OPTION_TYPE_TEXTBOX,
  46. 'order' => 1,
  47. 'desc' => '<p>' . gettext('Amount of memory allocated to Imagick in megabytes. Set to <strong>0</strong> for unlimited memory.') . '</p><p class="notebox">' . gettext('<strong>Note</strong>: Image processing will be faster with a higher memory limit. However, if your server experiences problems with image processing, try setting this lower.') . '</p>'),
  48. gettext('CAPTCHA font size') => array( 'key' => 'magick_font_size',
  49. 'type' => OPTION_TYPE_TEXTBOX,
  50. 'order' => 2,
  51. 'desc' => gettext('The font size (in pixels) for CAPTCHAs. Default is <strong>18</strong>.'))
  52. );
  53. }
  54. return array();
  55. }
  56.  
  57. function canLoadMsg() {
  58. global $_imagick_present, $_imagick_version;
  59. if ($_imagick_present) {
  60. if (!$_imagick_version) {
  61. return gettext('The <strong><em>Imagick</em></strong> library version must be <strong>2.1.0</strong> or later.');
  62. }
  63. } else {
  64. return gettext('The <strong><em>Imagick</em></strong> extension is not available.');
  65. }
  66. return '';
  67. }
  68. }
  69.  
  70. /**
  71. * Zenphoto image manipulation functions using the Imagick library
  72. */
  73. if ($_zp_imagick_present && (getOption('use_Imagick') || !extension_loaded('gd'))) { // only define the functions if we have the proper versions
  74. $temp = new Imagick();
  75.  
  76. // Imagick::setResourceLimit() crashes if called statically (prior to 3.0.0RC1)
  77. $mem_lim = getOption('magick_mem_lim');
  78. if ($mem_lim > 0) {
  79. $temp->setResourceLimit(Imagick::RESOURCETYPE_MEMORY, $mem_lim);
  80. } else {
  81. $temp->setResourceLimit(Imagick::RESOURCETYPE_MEMORY, $temp->getResourceLimit(Imagick::RESOURCETYPE_MEMORY));
  82. }
  83.  
  84. // Imagick::getVersion() crashes if called statically (prior to ???)
  85. $version = $temp->getVersion();
  86. $_lib_Imagick_info = array();
  87. $_lib_Imagick_info['Library'] = sprintf(gettext('PHP Imagick library <em>%s</em><br /><em>%s</em>'), phpversion('imagick'), $version['versionString']);
  88.  
  89. $format_blacklist = array(
  90. // video formats
  91. 'AVI', 'M2V', 'M4V', 'MOV', 'MP4', 'MPEG', 'MPG', 'WMV',
  92. // text formats
  93. 'HTM', 'HTML', 'MAN', 'PDF', 'SHTML', 'TEXT', 'TXT', 'UBRL',
  94. // font formats
  95. 'DFONT', 'OTF', 'PFA', 'PFB', 'TTC', 'TTF',
  96. // GhostScript formats; 'MAN' and 'PDF' also require this
  97. 'EPI', 'EPS', 'EPS2', 'EPS3', 'EPSF', 'EPSI', 'EPT', 'EPT2', 'EPT3', 'PS', 'PS2', 'PS3',
  98. // other formats with lib dependencies, so possibly no decode delegate
  99. 'CGM', 'EMF', 'FIG', 'FPX', 'GPLT', 'HPGL', 'JBIG', 'RAD', 'WMF', 'WMZ',
  100. // just to be sure...
  101. 'ZIP'
  102. );
  103.  
  104. // Imagick::queryFormats() should not be called statically
  105. $formats = array_diff($temp->queryFormats(), $format_blacklist);
  106. $imgtypes = array_combine(array_map('strtoupper', $formats), array_map('strtolower', $formats));
  107. $_lib_Imagick_info += $imgtypes;
  108.  
  109. $temp->destroy();
  110. unset($mem_lim);
  111. unset($version);
  112. unset($format_blacklist);
  113. unset($fontmats);
  114. unset($imgtypes);
  115.  
  116. if (DEBUG_IMAGE) {
  117. debugLog('Loading ' . $_lib_Imagick_info['Library']);
  118. }
  119.  
  120. /**
  121. * Takes an image filename and returns an Imagick image object
  122. *
  123. * @param string $imagefile the full path and filename of the image to load
  124. * @return Imagick
  125. */
  126. function zp_imageGet($imgfile) {
  127. global $_lib_Imagick_info;
  128. $ext = getSuffix($imgfile);
  129. if (function_exists('memory_get_usage')) {
  130. memory_get_usage(); // force PHP garbage collection if possible
  131. }
  132. if (in_array($ext, $_lib_Imagick_info)) {
  133. return new Imagick($imgfile);
  134. }
  135. return false;
  136. }
  137.  
  138. /**
  139. * Outputs an image resource as a given type
  140. *
  141. * Imagick::setCompressionQuality() has no Imagick version information
  142. *
  143. * @param Imagick $im
  144. * @param string $type
  145. * @param string $filename
  146. * @param int $qual
  147. * @return bool
  148. */
  149. function zp_imageOutput($im, $type, $filename = NULL, $qual = 75) {
  150. $qual = max(min($qual, 100), 0);
  151. switch ($type) {
  152. case 'png':
  153. $im->setCompression(Imagick::COMPRESSION_ZIP);
  154. $im->setCompressionQuality($qual);
  155. break;
  156. case 'jpeg': case 'jpg':
  157. $im->setCompression(Imagick::COMPRESSION_JPEG);
  158. $im->setCompressionQuality($qual);
  159. break;
  160. }
  161. $im->setImageFormat($type);
  162. if ($filename == NULL) {
  163. header('Content-Type: image/' . $type);
  164. return print $im;
  165. }
  166. return $im->writeImage($filename);
  167. }
  168.  
  169. /**
  170. * Creates a true color image
  171. *
  172. * @param int $w the width of the image
  173. * @param int $h the height of the image
  174. * @return Imagick
  175. */
  176. function zp_createImage($w, $h) {
  177. $im = new Imagick();
  178. $im->newImage($w, $h, 'none');
  179. $im->setImageType(Imagick::IMGTYPE_TRUECOLOR);
  180. return $im;
  181. }
  182.  
  183. /**
  184. * Fills an image area
  185. *
  186. * Imagick::paintFloodFillfillImage() requires Imagick 2.1.0 or newer
  187. * Imagick::floodFillPaintImage() has no Imagick version information
  188. * Imagick::floodFillPaintImage() requires Imagick compiled against ImageMagick 6.3.8 or newer
  189. *
  190. * @param Imagick $image
  191. * @param int $x
  192. * @param int $y
  193. * @param color $color
  194. * @return bool
  195. */
  196. function zp_imageFill($image, $x, $y, $color) {
  197. // Imagick::getVersion() crashes if called statically (prior to ???)
  198. $temp = new Imagick();
  199. $version = $temp->getVersion();
  200. $temp->destroy();
  201.  
  202. if (dechex($version['versionNumber']) < 638) {
  203. return $image->paintFloodfillImage($color, 1, $color, $x, $y);
  204. }
  205.  
  206. $target = $image->getImagePixelColor($x, $y);
  207. return $image->floodFillPaintImage($color, 1, $target, $x, $y);
  208. }
  209.  
  210. /**
  211. * Sets the transparency color
  212. *
  213. * Imagick::transparentPaintImage() has no Imagick version information
  214. * Imagick::transparentPaintImage() requires Imagick compiled against ImageMagick 6.3.8 or newer
  215. *
  216. * @param Imagick $image
  217. * @param color $color
  218. * @return bool
  219. */
  220. function zp_imageColorTransparent($image, $color) {
  221. // Imagick::getVersion() crashes if called statically (prior to ???)
  222. $temp = new Imagick();
  223. $version = $temp->getVersion();
  224. $temp->destroy();
  225.  
  226. if (dechex($version['versionNumber']) < 638) {
  227. return $image->paintTransparentImage($color, 0.0, 1);
  228. }
  229.  
  230. return $image->transparentPaintImage($color, 0.0, 1, false);
  231. }
  232.  
  233. /**
  234. * Copies an image canvas
  235. *
  236. * @param Imagick $imgCanvas destination canvas
  237. * @param Imagick $img source canvas
  238. * @param int $dest_x destination x
  239. * @param int $dest_y destination y
  240. * @param int $src_x source x
  241. * @param int $src_y source y
  242. * @param int $w width
  243. * @param int $h height
  244. * @return bool
  245. */
  246. function zp_copyCanvas($imgCanvas, $img, $dest_x, $dest_y, $src_x, $src_y, $w, $h) {
  247. $img->cropImage($w, $h, $src_x, $src_y);
  248. return $imgCanvas->compositeImage($img, Imagick::COMPOSITE_COPY, $dest_x, $dest_y);
  249. }
  250.  
  251. /**
  252. * Resamples an image to a new copy
  253. *
  254. * @param Imagick $dst_image
  255. * @param Imagick $src_image
  256. * @param int $dst_x
  257. * @param int $dst_y
  258. * @param int $src_x
  259. * @param int $src_y
  260. * @param int $dst_w
  261. * @param int $dst_h
  262. * @param int $src_w
  263. * @param int $src_h
  264. * @param string $suffix
  265. * @return bool
  266. */
  267. function zp_resampleImage($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $suffix) {
  268. $src_image->cropImage($src_w, $src_h, $src_x, $src_y);
  269. $src_image->resizeImage($dst_w, $dst_h, Imagick::FILTER_LANCZOS, 1);
  270. return $dst_image->compositeImage($src_image, Imagick::COMPOSITE_OVER, $dst_x, $dst_y);
  271. }
  272.  
  273. /**
  274. * Sharpens an image using an Unsharp Mask filter.
  275. *
  276. * @param Imagick $img the image to sharpen
  277. * @param int $amount the strength of the sharpening effect
  278. * @param int $radius the pixel radius of the sharpening mask
  279. * @param int $threshold the color difference threshold required for sharpening
  280. * @return Imagick
  281. */
  282. function zp_imageUnsharpMask($img, $amount, $radius, $threshold) {
  283. $img->unsharpMaskImage($radius, 0.1, $amount, $threshold);
  284. return $img;
  285. }
  286.  
  287. /**
  288. * Resize a file with transparency to given dimensions and still retain the alpha channel information
  289. *
  290. * @param Imagick $src
  291. * @param int $w
  292. * @param int $h
  293. * @return Imagick
  294. */
  295. function zp_imageResizeAlpha($src, $w, $h) {
  296. $src->scaleImage($w, $h);
  297. return $src;
  298. }
  299.  
  300. /**
  301. * Returns true if Imagick library is configued with image rotation support
  302. *
  303. * @return bool
  304. */
  305. function zp_imageCanRotate() {
  306. global $_imagick_can_rotate;
  307. if (is_null($_imagick_can_rotate)) {
  308. $_imagick_can_rotate = in_array(strtolower('rotateImage'), array_map('strtolower', get_class_methods('Imagick')));
  309. }
  310. return $_imagick_can_rotate;
  311. }
  312.  
  313. /**
  314. * Rotates an image resource according to its EXIF info and auto_rotate option
  315. *
  316. * @param Imagick $im
  317. * @param int $rotate
  318. * @return Imagick
  319. */
  320. function zp_rotateImage($im, $rotate) {
  321. $im->rotateImage(0, 360 - $rotate); // GD rotates CCW, Imagick rotates CW
  322. return $im;
  323. }
  324.  
  325. /**
  326. * Returns the image height and width
  327. *
  328. * @param string $filename
  329. * @param array $imageinfo
  330. * @return array
  331. */
  332. function zp_imageDims($filename) {
  333. $ping = new Imagick();
  334. if ($ping->pingImage($filename)) {
  335. return array('width'=>$ping->getImageWidth(), 'height'=>$ping->getImageHeight());
  336. }
  337. return false;
  338. }
  339.  
  340. /**
  341. * Returns the IPTC data of an image
  342. *
  343. * @param string $filename
  344. * @throws ImagickException
  345. * @return string
  346. */
  347. function zp_imageIPTC($filename) {
  348. $ping = new Imagick();
  349. if ($ping->pingImage($filename)) {
  350. try {
  351. return $ping->getImageProfile('exif');
  352. } catch (ImagickException $e) {
  353. if (DEBUG_IMAGE) {
  354. debugLog('Caught ImagickException in zp_imageIPTC(): ' . $e->getMessage());
  355. }
  356. }
  357. }
  358. return false;
  359. }
  360.  
  361. /**
  362. * Returns the width of an image resource
  363. *
  364. * @param Imagick $im
  365. * @return int
  366. */
  367. function zp_imageWidth($im) {
  368. return $im->getImageWidth();
  369. }
  370.  
  371. /**
  372. * Returns the height of an image resource
  373. *
  374. * @param Imagick $im
  375. * @return int
  376. */
  377. function zp_imageHeight($im) {
  378. return $im->getImageHeight();
  379. }
  380.  
  381. /**
  382. * Does a copy merge of two image resources
  383. *
  384. * Imagick::setImageOpacity() requires Imagick compiled against ImageMagick 6.3.1 or newer
  385. *
  386. * @param Imagick $dst_im
  387. * @param Imagick $src_im
  388. * @param int $dst_x
  389. * @param int $dst_y
  390. * @param int $src_x
  391. * @param int $src_y
  392. * @param int $src_w
  393. * @param int $src_h
  394. * @param int $pct
  395. * @return bool
  396. */
  397. function zp_imageMerge($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) {
  398. // Imagick::getVersion() crashes if called statically (prior to ???)
  399. $temp = new Imagick();
  400. $version = $temp->getVersion();
  401. $temp->destroy();
  402.  
  403. $src_im->cropImage($w, $h, $src_x, $src_y);
  404.  
  405. if (dechex($version['versionNumber']) < 631) {
  406. $src_im->setImageType(Imagick::IMGTYPE_GRAYSCALE);
  407. } else {
  408. $src_im->setImageOpacity($pct / 100);
  409. }
  410.  
  411. return $dst_im->compositeImage($src_im, Imagick::COMPOSITE_ATOP, $dest_x, $dest_y);
  412. }
  413.  
  414. /**
  415. * Creates a grayscale image
  416. *
  417. * @param Imagick $image
  418. * @return Imagick
  419. */
  420. function zp_imageGray($image) {
  421. $image->setImageType(Imagick::IMGTYPE_GRAYSCALE);
  422. return $image;
  423. }
  424.  
  425. /**
  426. * Destroys an image resource
  427. *
  428. * @param Imagick $im
  429. * @return bool
  430. */
  431. function zp_imageKill($im) {
  432. return $im->destroy();
  433. }
  434.  
  435. /**
  436. * Returns an RGB color identifier
  437. *
  438. * @param Imagick $image
  439. * @param int $red
  440. * @param int $green
  441. * @param int $blue
  442. * @return ImagickPixel
  443. */
  444. function zp_colorAllocate($image, $red, $green, $blue) {
  445. return new ImagickPixel("rgb($red, $green, $blue)");
  446. }
  447.  
  448. /**
  449. * Renders a string into the image
  450. *
  451. * @param Imagick $image
  452. * @param ImagickDraw $font
  453. * @param int $x
  454. * @param int $y
  455. * @param string $string
  456. * @param ImagickPixel $color
  457. * @return bool
  458. */
  459. function zp_writeString($image, $font, $x, $y, $string, $color) {
  460. $font->setStrokeColor($color);
  461. return $image->annotateImage($font, $x, $y + $image->getImageHeight() / 2, 0, $string);
  462. }
  463.  
  464. /**
  465. * Creates a rectangle
  466. *
  467. * @param Imagick $image
  468. * @param int $x1
  469. * @param int $y1
  470. * @param int $x2
  471. * @param int $y2
  472. * @param ImagickPixel $color
  473. * @return bool
  474. */
  475. function zp_drawRectangle($image, $x1, $y1, $x2, $y2, $color) {
  476. return $image->borderImage($color, 1, 1);
  477. }
  478.  
  479. /**
  480. * Returns array of graphics library info
  481. *
  482. * @return array
  483. */
  484. function zp_graphicsLibInfo() {
  485. global $_lib_Imagick_info;
  486. return $_lib_Imagick_info;
  487. }
  488.  
  489. /**
  490. * Returns a list of available fonts
  491. *
  492. * @return array
  493. */
  494. function zp_getFonts() {
  495. global $_imagick_fontlist;
  496. if (!is_array($_imagick_fontlist)) {
  497. // Imagick::queryFonts() should not be called statically
  498. $temp = new Imagick();
  499. $_imagick_fontlist = $temp->queryFonts();
  500. $temp->destroy();
  501. $_imagick_fontlist = array('system' => '') + array_combine($_imagick_fontlist, $_imagick_fontlist);
  502.  
  503. $basefile = SERVERPATH . '/' . USER_PLUGIN_FOLDER . '/imagick_fonts/';
  504. if (is_dir($basefile)) {
  505. chdir($basefile);
  506. $filelist = safe_glob('*.ttf');
  507. foreach($filelist as $file) {
  508. $key = filesystemToInternal(str_replace('.ttf', '', $file));
  509. $_imagick_fontlist[$key] = getcwd() . '/' . $file;
  510. }
  511. }
  512.  
  513. /** If Zenphoto distributes its own fonts, uncomment
  514. * chdir($basefile = SERVERPATH . '/' . ZENFOLDER . '/imagick_fonts/');
  515. * $filelist = safe_glob('*.ttf');
  516. * foreach($filelist as $file) {
  517. * $key = filesystemToInternal(str_replace('.ttf', '', $file));
  518. * $_imagick_fontlist[$key] = getcwd() . '/' . $file;
  519. * }
  520. */
  521. chdir(dirname(__FILE__));
  522. }
  523. return $_imagick_fontlist;
  524. }
  525.  
  526. /**
  527. * Loads a font and returns an object with the font loaded
  528. *
  529. * @param string $font
  530. * @return ImagickDraw
  531. */
  532. function zp_imageLoadFont($font = NULL) {
  533. $draw = new ImagickDraw();
  534. if (!empty($font)) {
  535. try {
  536. $draw->setFont($font);
  537. } catch(ImagickDrawException $e) {
  538. if (DEBUG_IMAGE) {
  539. debugLog('Caught ImagickDrawException in zp_imageLoadFont(): ' . $e->getMessage());
  540. }
  541. }
  542. }
  543. $draw->setFontSize(getOption('magick_font_size'));
  544. return $draw;
  545. }
  546.  
  547. /**
  548. * Returns the font width in pixels
  549. *
  550. * @param ImagickDraw $font
  551. * @return int
  552. */
  553. function zp_imageFontWidth($font) {
  554. $temp = new Imagick();
  555. $metrics = $temp->queryFontMetrics($font, "The quick brown fox jumps over the lazy dog");
  556. $temp->destroy();
  557. return $metrics['characterWidth'];
  558. }
  559.  
  560. /**
  561. * Returns the font height in pixels
  562. *
  563. * @param ImagickDraw $font
  564. * @return int
  565. */
  566. function zp_imageFontHeight($font) {
  567. $temp = new Imagick();
  568. $metrics = $temp->queryFontMetrics($font, "The quick brown fox jumps over the lazy dog");
  569. $temp->destroy();
  570. return $metrics['characterHeight'];
  571. }
  572. }
  573.  
  574. ?>
Advertisement
Add Comment
Please, Sign In to add comment