PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/util/Image_Toolbox.php

https://github.com/jcorbinredtree/framework
PHP | 1448 lines | 996 code | 93 blank | 359 comment | 195 complexity | 8630c850e9a4097bd6d7de3cad077cc7 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Image_Toolbox.class.php -- PHP image manipulation class
  4. *
  5. * Copyright (C) 2003 Martin Theimer <pappkamerad@decoded.net>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License <http://www.opensource.org/gpl-license.html>
  15. * for more details..
  16. *
  17. * The latest version of Image_Toolbox can be obtained from:
  18. * http://sourceforge.net/projects/image-toolbox
  19. * http://www.phpclasses.org/image_toolbox
  20. *
  21. * @author Martin Theimer <pappkamerad@decoded.net>
  22. * @copyright Copyright (C) 2003 Martin Theimer
  23. * @version 1.1.0
  24. * @package Image_Toolbox
  25. * @link http://sourceforge.net/projects/image-toolbox
  26. */
  27. // $Id: Image_Toolbox.class.php,v 1.9 2003/12/05 19:34:01 pappkamerad Exp $
  28. if (!defined('IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY')) {
  29. define('IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY', 75);
  30. }
  31. if (!defined('IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS')) {
  32. define('IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS', 256);
  33. }
  34. if (!defined('IMAGE_TOOLBOX_BIAS_HORIZONTAL')) {
  35. define('IMAGE_TOOLBOX_BIAS_HORIZONTAL', 1);
  36. }
  37. if (!defined('IMAGE_TOOLBOX_BIAS_VERTICAL')) {
  38. define('IMAGE_TOOLBOX_BIAS_VERTICAL', 0);
  39. }
  40. if (!defined('IMAGE_TOOLBOX_BLEND_COPY')) {
  41. define('IMAGE_TOOLBOX_BLEND_COPY', 1);
  42. }
  43. if (!defined('IMAGE_TOOLBOX_BLEND_MULTIPLY')) {
  44. define('IMAGE_TOOLBOX_BLEND_MULTIPLY', 2);
  45. }
  46. if (!defined('IMAGE_TOOLBOX_BLEND_SCREEN')) {
  47. define('IMAGE_TOOLBOX_BLEND_SCREEN', 3);
  48. }
  49. if (!defined('IMAGE_TOOLBOX_BLEND_DIFFERENCE')) {
  50. define('IMAGE_TOOLBOX_BLEND_DIFFERENCE', 4);
  51. }
  52. if (!defined('IMAGE_TOOLBOX_BLEND_NEGATION')) {
  53. define('IMAGE_TOOLBOX_BLEND_NEGATION', 5);
  54. }
  55. if (!defined('IMAGE_TOOLBOX_BLEND_EXCLUTION')) {
  56. define('IMAGE_TOOLBOX_BLEND_EXCLUSION', 6);
  57. }
  58. if (!defined('IMAGE_TOOLBOX_BLEND_OVERLAY')) {
  59. define('IMAGE_TOOLBOX_BLEND_OVERLAY', 7);
  60. }
  61. /**
  62. * PHP image manipulation class
  63. *
  64. * This class provides an easy to use library to the PHP GD-based imagefunctions
  65. *
  66. * @author Martin Theimer <pappkamerad@decoded.net>
  67. * @copyright 2003, Martin Theimer
  68. * @package Image_Toolbox
  69. * @link http://sourceforge.net/projects/image-toolbox
  70. * @version 1.1.0
  71. */
  72. class Image_Toolbox
  73. {
  74. /**
  75. * The prefix for every error message
  76. *
  77. * @access private
  78. * @var string
  79. */
  80. var $_error_prefix = 'Image: ';
  81. /**
  82. * Defines imagetypes and how they are supported by the server
  83. *
  84. * @access private
  85. * @var array
  86. */
  87. var $_types = array (
  88. 1 => array (
  89. 'ext' => 'gif',
  90. 'mime' => 'image/gif',
  91. 'supported' => 0
  92. ),
  93. 2 => array (
  94. 'ext' => 'jpg',
  95. 'mime' => 'image/jpeg',
  96. 'supported' => 0
  97. ),
  98. 3 => array (
  99. 'ext' => 'png',
  100. 'mime' => 'image/png',
  101. 'supported' => 0
  102. )
  103. );
  104. /**
  105. * Which PHP image resize function to be used
  106. * imagecopyresampled only supported with GD >= 2.0
  107. *
  108. * @access private
  109. * @var string
  110. */
  111. var $_resize_function = 'imagecopyresampled';
  112. /**
  113. * Stores all image resource data
  114. *
  115. * @access private
  116. * @var array
  117. */
  118. var $_img = array (
  119. 'main' => array (
  120. 'resource' => 0,
  121. 'width' => 0,
  122. 'height' => 0,
  123. 'bias' => 0,
  124. 'aspectratio' => 0,
  125. 'type' => 0,
  126. 'output_type' => 0,
  127. 'indexedcolors' => 0,
  128. 'color' => -1
  129. )
  130. );
  131. /**
  132. * Which PHP image create function to be used
  133. * imagecreatetruecolor only supported with GD >= 2.0
  134. *
  135. * @access private
  136. * @var string
  137. */
  138. var $_imagecreatefunction = '';
  139. /**
  140. * The class constructor.
  141. *
  142. * Determines the image features of the server and sets the according values.<br>
  143. * Additionally you can specify a image to be created/loaded. like {@link addImage() addImage}.
  144. *
  145. * If no parameter is given, no image resource will be generated<br>
  146. * Or:<br>
  147. * <i>string</i> <b>$file</b> imagefile to load<br>
  148. * Or:<br>
  149. * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  150. * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  151. * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  152. */
  153. function Image_Toolbox()
  154. {
  155. $args = func_get_args();
  156. $argc = func_num_args();
  157. //get GD information. see what types we can handle
  158. $gd_info = function_exists('gd_info') ? gd_info() : $this->_gd_info();
  159. preg_match("/\A[\D]*([\d+\.]*)[\D]*\Z/", $gd_info['GD Version'], $matches);
  160. list($this->_gd_version_string, $this->_gd_version_number) = $matches;
  161. $this->_gd_version = substr($this->_gd_version_number, 0, strpos($this->_gd_version_number, '.'));
  162. if ($this->_gd_version >= 2) {
  163. $this->_imagecreatefunction = 'imagecreatetruecolor';
  164. $this->_resize_function = 'imagecopyresampled';
  165. } else {
  166. $this->_imagecreatefunction = 'imagecreate';
  167. $this->_resize_function = 'imagecopyresized';
  168. }
  169. $this->_gd_ttf = $gd_info['FreeType Support'];
  170. $this->_gd_ps = $gd_info['T1Lib Support'];
  171. if ($gd_info['GIF Read Support']) {
  172. $this->_types[1]['supported'] = 1;
  173. if ($gd_info['GIF Create Support']) {
  174. $this->_types[1]['supported'] = 2;
  175. }
  176. }
  177. if ($gd_info['JPG Support']) {
  178. $this->_types[2]['supported'] = 2;
  179. }
  180. if ($gd_info['PNG Support']) {
  181. $this->_types[3]['supported'] = 2;
  182. }
  183. //load or create main image
  184. if ($argc == 0) {
  185. return true;
  186. } else {
  187. if ($this->_addImage($argc, $args)) {
  188. foreach ($this->_img['operator'] as $key => $value) {
  189. $this->_img['main'][$key] = $value;
  190. }
  191. $this->_img['main']['output_type'] = $this->_img['main']['type'];
  192. unset($this->_img['operator']);
  193. return true;
  194. } else {
  195. trigger_error($this->_error_prefix . 'No appropriate constructor found.', E_USER_ERROR);
  196. return null;
  197. }
  198. }
  199. }
  200. /**
  201. * Returns an assocative array with information about the image features of this server
  202. *
  203. * Array values:
  204. * <ul>
  205. * <li>'gd_version' -> what GD version is installed on this server (e.g. 2.0)</li>
  206. * <li>'gif' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>
  207. * <li>'jpg' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>
  208. * <li>'png' -> 0 = not supported, 1 = reading is supported, 2 = creating is supported</li>
  209. * <li>'ttf' -> TTF text creation. true = supported, false = not supported
  210. * </ul>
  211. *
  212. * @return array
  213. */
  214. function getServerFeatures()
  215. {
  216. $features = array();
  217. $features['gd_version'] = $this->_gd_version_number;
  218. $features['gif'] = $this->_types[1]['supported'];
  219. $features['jpg'] = $this->_types[2]['supported'];
  220. $features['png'] = $this->_types[3]['supported'];
  221. $features['ttf'] = $this->_gd_ttf;
  222. return $features;
  223. }
  224. /**
  225. * Flush all image resources and init a new one
  226. *
  227. * Parameter:<br>
  228. * <i>string</i> <b>$file</b> imagefile to load<br>
  229. * Or:<br>
  230. * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  231. * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  232. * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  233. */
  234. function newImage()
  235. {
  236. $args = func_get_args();
  237. $argc = func_num_args();
  238. if ($this->_addImage($argc, $args)) {
  239. foreach ($this->_img['operator'] as $key => $value) {
  240. $this->_img['main'][$key] = $value;
  241. }
  242. $this->_img['main']['output_type'] = $this->_img['main']['type'];
  243. unset($this->_img['operator']);
  244. return true;
  245. } else {
  246. trigger_error($this->_error_prefix . 'No appropriate constructor found.', E_USER_ERROR);
  247. return null;
  248. }
  249. }
  250. /**
  251. * Reimplements the original PHP {@link gd_info()} function for older PHP versions
  252. *
  253. * @access private
  254. * @return array associative array with info about the GD library of the server
  255. */
  256. function _gd_info()
  257. {
  258. $array = array(
  259. "GD Version" => "",
  260. "FreeType Support" => false,
  261. "FreeType Linkage" => "",
  262. "T1Lib Support" => false,
  263. "GIF Read Support" => false,
  264. "GIF Create Support" => false,
  265. "JPG Support" => true,
  266. "PNG Support" => false,
  267. "WBMP Support" => false,
  268. "XBM Support" => false
  269. );
  270. $gif_support = 0;
  271. ob_start();
  272. eval("phpinfo();");
  273. $info = ob_get_contents();
  274. ob_end_clean();
  275. foreach(explode("\n", $info) as $line) {
  276. if(strpos($line, "GD Version") !== false)
  277. $array["GD Version"] = trim(str_replace("GD Version", "", strip_tags($line)));
  278. if(strpos($line, "FreeType Support") !== false)
  279. $array["FreeType Support"] = trim(str_replace("FreeType Support", "", strip_tags($line)));
  280. if(strpos($line, "FreeType Linkage") !== false)
  281. $array["FreeType Linkage"] = trim(str_replace("FreeType Linkage", "", strip_tags($line)));
  282. if(strpos($line, "T1Lib Support") !== false)
  283. $array["T1Lib Support"] = trim(str_replace("T1Lib Support", "", strip_tags($line)));
  284. if(strpos($line, "GIF Read Support") !== false)
  285. $array["GIF Read Support"] = trim(str_replace("GIF Read Support", "", strip_tags($line)));
  286. if(strpos($line, "GIF Create Support") !== false)
  287. $array["GIF Create Support"] = trim(str_replace("GIF Create Support", "", strip_tags($line)));
  288. if(strpos($line, "GIF Support") !== false)
  289. $gif_support = trim(str_replace("GIF Support", "", strip_tags($line)));
  290. if(strpos($line, "JPG Support") !== false)
  291. $array["JPG Support"] = trim(str_replace("JPG Support", "", strip_tags($line)));
  292. if(strpos($line, "PNG Support") !== false)
  293. $array["PNG Support"] = trim(str_replace("PNG Support", "", strip_tags($line)));
  294. if(strpos($line, "WBMP Support") !== false)
  295. $array["WBMP Support"] = trim(str_replace("WBMP Support", "", strip_tags($line)));
  296. if(strpos($line, "XBM Support") !== false)
  297. $array["XBM Support"] = trim(str_replace("XBM Support", "", strip_tags($line)));
  298. }
  299. if($gif_support === "enabled") {
  300. $array["GIF Read Support"] = true;
  301. $array["GIF Create Support"] = true;
  302. }
  303. if($array["FreeType Support"] === "enabled") {
  304. $array["FreeType Support"] = true;
  305. }
  306. if($array["T1Lib Support"] === "enabled") {
  307. $array["T1Lib Support"] = true;
  308. }
  309. if($array["GIF Read Support"] === "enabled") {
  310. $array["GIF Read Support"] = true;
  311. }
  312. if($array["GIF Create Support"] === "enabled") {
  313. $array["GIF Create Support"] = true;
  314. }
  315. if($array["JPG Support"] === "enabled") {
  316. $array["JPG Support"] = true;
  317. }
  318. if($array["PNG Support"] === "enabled") {
  319. $array["PNG Support"] = true;
  320. }
  321. if($array["WBMP Support"] === "enabled") {
  322. $array["WBMP Support"] = true;
  323. }
  324. if($array["XBM Support"] === "enabled") {
  325. $array["XBM Support"] = true;
  326. }
  327. return $array;
  328. }
  329. /**
  330. * Convert a color defined in hexvalues to the PHP color format
  331. *
  332. * @access private
  333. * @param string $hex color value in hexformat (e.g. '#FF0000')
  334. * @return integer color value in PHP format
  335. */
  336. function _hexToPHPColor($hex)
  337. {
  338. $length = strlen($hex);
  339. $dr = hexdec(substr($hex, $length - 6, 2));
  340. $dg = hexdec(substr($hex, $length - 4, 2));
  341. $db = hexdec(substr($hex, $length - 2, 2));
  342. $color = ($dr << 16) + ($dg << 8) + $db;
  343. return $color;
  344. }
  345. /**
  346. * Convert a color defined in hexvalues to corresponding dezimal values
  347. *
  348. * @access private
  349. * @param string $hex color value in hexformat (e.g. '#FF0000')
  350. * @return array associative array with color values in dezimal format (fields: 'red', 'green', 'blue')
  351. */
  352. function _hexToDecColor($hex)
  353. {
  354. $length = strlen($hex);
  355. $color['red'] = hexdec(substr($hex, $length - 6, 2));
  356. $color['green'] = hexdec(substr($hex, $length - 4, 2));
  357. $color['blue'] = hexdec(substr($hex, $length - 2, 2));
  358. return $color;
  359. }
  360. /**
  361. * Generate a new image resource based on the given parameters
  362. *
  363. * Parameter:
  364. * <i>string</i> <b>$file</b> imagefile to load<br>
  365. * Or:<br>
  366. * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  367. * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  368. * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  369. *
  370. * @access private
  371. */
  372. function _addImage($argc, $args)
  373. {
  374. if (($argc == 2 || $argc == 3) && is_int($args[0]) && is_int($args[1]) && (is_string($args[2]) || !isset($args[2]))) {
  375. //neues leeres bild mit width und height (fillcolor optional)
  376. $this->_img['operator']['width'] = $args[0];
  377. $this->_img['operator']['height'] = $args[1];
  378. ($this->_img['operator']['width'] >= $this->_img['operator']['height']) ? ($this->_img['operator']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['operator']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  379. $this->_img['operator']['aspectratio'] = $this->_img['operator']['width'] / $this->_img['operator']['height'];
  380. $this->_img['operator']['indexedcolors'] = 0;
  381. $functionname = $this->_imagecreatefunction;
  382. $this->_img['operator']['resource'] = $functionname($this->_img['operator']['width'], $this->_img['operator']['height']);
  383. // set default type jpg.
  384. $this->_img['operator']['type'] = 2;
  385. if (isset($args[2]) && is_string($args[2])) {
  386. //neues bild mit farbe f�llen
  387. $fillcolor = $this->_hexToPHPColor($args[2]);
  388. imagefill($this->_img['operator']['resource'], 0, 0, $fillcolor);
  389. $this->_img['operator']['color'] = $fillcolor;
  390. } else {
  391. $this->_img['operator']['color'] = 0;
  392. }
  393. } elseif ($argc == 1 && is_string($args[0])) {
  394. //bild aus datei laden. width und height original gr�sse
  395. $this->_img['operator'] = $this->_loadFile($args[0]);
  396. $this->_img['operator']['indexedcolors'] = imagecolorstotal($this->_img['operator']['resource']);
  397. $this->_img['operator']['color'] = -1;
  398. } else {
  399. return false;
  400. }
  401. return true;
  402. }
  403. /**
  404. * Loads a image file
  405. *
  406. * @access private
  407. * @param string $filename imagefile to load
  408. * @return array associative array with the loaded filedata
  409. */
  410. function _loadFile($filename)
  411. {
  412. if (file_exists($filename)) {
  413. $info = getimagesize($filename);
  414. $filedata['width'] = $info[0];
  415. $filedata['height'] = $info[1];
  416. ($filedata['width'] >= $filedata['height']) ? ($filedata['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($filedata['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  417. $filedata['aspectratio'] = $filedata['width'] / $filedata['height'];
  418. $filedata['type'] = $info[2];
  419. if ($this->_types[$filedata['type']]['supported'] < 1) {
  420. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$filedata['type']]['ext'].') not supported for reading.', E_USER_ERROR);
  421. return null;
  422. }
  423. switch ($filedata['type']) {
  424. case 1:
  425. $dummy = imagecreatefromgif($filename);
  426. $functionname = $this->_imagecreatefunction;
  427. $filedata['resource'] = $functionname($filedata['width'], $filedata['height']);
  428. imagecopy($filedata['resource'], $dummy, 0, 0, 0, 0, $filedata['width'], $filedata['height']);
  429. imagedestroy($dummy);
  430. break;
  431. case 2:
  432. $filedata['resource'] = imagecreatefromjpeg($filename);
  433. break;
  434. case 3:
  435. $dummy = imagecreatefrompng($filename);
  436. if (imagecolorstotal($dummy) != 0) {
  437. $functionname = $this->_imagecreatefunction;
  438. $filedata['resource'] = $functionname($filedata['width'], $filedata['height']);
  439. imagecopy($filedata['resource'], $dummy, 0, 0, 0, 0, $filedata['width'], $filedata['height']);
  440. } else {
  441. $filedata['resource'] = $dummy;
  442. }
  443. unset($dummy);
  444. break;
  445. default:
  446. trigger_error($this->_error_prefix . 'Imagetype not supported.', E_USER_ERROR);
  447. return null;
  448. }
  449. return $filedata;
  450. } else {
  451. trigger_error($this->_error_prefix . 'Imagefile (' . $filename . ') does not exist.', E_USER_ERROR);
  452. return null;
  453. }
  454. }
  455. /**
  456. * Output a image to the browser
  457. *
  458. * $output_type can be one of the following:<br>
  459. * <ul>
  460. * <li>'gif' -> gif image (if supported) (8-bit indexed colors)</li>
  461. * <li>'png' -> png image (if supported) (truecolor)</li>
  462. * <li>'png8' -> png image (if supported) (8-bit indexed colors)</li>
  463. * <li>'jpg' -> jpeg image (if supported) (truecolor)</li>
  464. * </ul>
  465. * (default: same as original)
  466. *
  467. * $dither:<br>
  468. * If this is true than dither is used on the conversion from truecolor to 8-bit indexed imageformats (png8, gif)<br>
  469. * (default = false)
  470. *
  471. * @param string|integer $output_type type of outputted image
  472. * @param integer $output_quality jpeg quality of outputted image (default: IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY)
  473. * @param bool $dither use dither
  474. * @return bool true on success, otherwise false
  475. */
  476. function output($output_type = false, $output_quality = false, $dither = false)
  477. {
  478. if ($output_type === false) {
  479. $output_type = $this->_img['main']['output_type'];
  480. }
  481. switch ($output_type) {
  482. case 1:
  483. case 'gif':
  484. case 'GIF':
  485. if ($this->_types[1]['supported'] < 2) {
  486. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  487. return null;
  488. }
  489. header ('Content-type: ' . $this->_types[$output_type]['mime']);
  490. if ($this->_gd_version >= 2) {
  491. if ($this->_img['main']['indexedcolors'] == 0) {
  492. $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  493. imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  494. if ($output_quality === false) {
  495. $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  496. }
  497. imagetruecolortopalette($dummy, $dither, $output_quality);
  498. }
  499. imagegif($dummy);
  500. imagedestroy($dummy);
  501. }
  502. else {
  503. imagegif($this->_img['main']['resource']);
  504. }
  505. break;
  506. case 2:
  507. case '2':
  508. case 'jpg':
  509. case 'jpeg':
  510. case 'JPG':
  511. case 'JPEG':
  512. if ($this->_types[2]['supported'] < 2) {
  513. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  514. return null;
  515. }
  516. header ('Content-type: ' . $this->_types[$output_type]['mime']);
  517. if ($output_quality === false) {
  518. $output_quality = IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY;
  519. }
  520. imagejpeg($this->_img['main']['resource'], '', $output_quality);
  521. break;
  522. case 3:
  523. case '3':
  524. case 'png':
  525. case 'PNG':
  526. case 'png24':
  527. case 'PNG24':
  528. if ($this->_types[3]['supported'] < 2) {
  529. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  530. return null;
  531. }
  532. header ('Content-type: ' . $this->_types[$output_type]['mime']);
  533. imagepng($this->_img['main']['resource']);
  534. break;
  535. case 4:
  536. case '4':
  537. case 'png8':
  538. case 'PNG8':
  539. if ($this->_types[3]['supported'] < 2) {
  540. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  541. return null;
  542. }
  543. header ('Content-type: ' . $this->_types[$output_type]['mime']);
  544. if ($this->_gd_version >= 2) {
  545. if ($this->_img['main']['indexedcolors'] == 0) {
  546. $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  547. imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  548. if ($output_quality === false) {
  549. $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  550. }
  551. imagetruecolortopalette($dummy, $dither, $output_quality);
  552. }
  553. imagepng($dummy);
  554. imagedestroy($dummy);
  555. }
  556. else {
  557. imagepng($this->_img['main']['resource']);
  558. }
  559. break;
  560. default:
  561. trigger_error($this->_error_prefix . 'Output-Imagetype not supported.', E_USER_ERROR);
  562. return null;
  563. }
  564. return true;
  565. }
  566. function getResource()
  567. {
  568. return $this->_img['main']['resource'];
  569. }
  570. function asString()
  571. {
  572. ob_start();
  573. imagejpeg($this->_img['main']['resource'], null, IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY);
  574. $string = ob_get_contents();
  575. ob_end_clean();
  576. return $string;
  577. }
  578. /**
  579. * Save a image to disk
  580. *
  581. * $output_type can be one of the following:<br>
  582. * <ul>
  583. * <li>'gif' -> gif image (if supported) (8-bit indexed colors)</li>
  584. * <li>'png' -> png image (if supported) (truecolor)</li>
  585. * <li>'png8' -> png image (if supported) (8-bit indexed colors)</li>
  586. * <li>'jpg' -> jpeg image (if supported) (truecolor)</li>
  587. * </ul>
  588. * (default: same as original)
  589. *
  590. * $dither:<br>
  591. * If this is true than dither is used on the conversion from truecolor to 8-bit indexed imageformats (png8, gif)<br>
  592. * (default = false)
  593. *
  594. * @param string $filename filename of saved image
  595. * @param string|integer $output_type type of saved image
  596. * @param integer $output_quality jpeg quality of saved image (default: IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY)
  597. * @param bool $dither use dither
  598. * @return bool true on success, otherwise false
  599. */
  600. function save($filename, $output_type = false, $output_quality = false, $dither = false)
  601. {
  602. if ($output_type === false) {
  603. $output_type = $this->_img['main']['output_type'];
  604. }
  605. switch ($output_type) {
  606. case 1:
  607. case 'gif':
  608. case 'GIF':
  609. if ($this->_types[1]['supported'] < 2) {
  610. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  611. return null;
  612. }
  613. if ($this->_gd_version >= 2) {
  614. if ($this->_img['main']['indexedcolors'] == 0) {
  615. $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  616. imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  617. if ($output_quality === false) {
  618. $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  619. }
  620. imagetruecolortopalette($dummy, $dither, $output_quality);
  621. }
  622. imagegif($dummy, $filename);
  623. imagedestroy($dummy);
  624. }
  625. else {
  626. imagegif($this->_img['main']['resource']);
  627. }
  628. break;
  629. case 2:
  630. case '2':
  631. case 'jpg':
  632. case 'jpeg':
  633. case 'JPG':
  634. case 'JPEG':
  635. if ($this->_types[2]['supported'] < 2) {
  636. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  637. return null;
  638. }
  639. if ($output_quality === false) {
  640. $output_quality = IMAGE_TOOLBOX_DEFAULT_JPEG_QUALITY;
  641. }
  642. imagejpeg($this->_img['main']['resource'], $filename, $output_quality);
  643. break;
  644. case 3:
  645. case '3':
  646. case 'png':
  647. case 'PNG':
  648. case 'png24':
  649. case 'PNG24':
  650. if ($this->_types[3]['supported'] < 2) {
  651. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  652. return null;
  653. }
  654. header ('Content-type: ' . $this->_types[$output_type]['mime']);
  655. imagepng($this->_img['main']['resource'], $filename);
  656. break;
  657. case 4:
  658. case '4':
  659. case 'png8':
  660. case 'PNG8':
  661. if ($this->_types[3]['supported'] < 2) {
  662. trigger_error($this->_error_prefix . 'Imagetype ('.$this->_types[$output_type]['ext'].') not supported for creating/writing.', E_USER_ERROR);
  663. return null;
  664. }
  665. if ($this->_gd_version >= 2) {
  666. if ($this->_img['main']['indexedcolors'] == 0) {
  667. $dummy = imagecreatetruecolor($this->_img['main']['width'], $this->_img['main']['height']);
  668. imagecopy($dummy, $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  669. if ($output_quality === false) {
  670. $output_quality = IMAGE_TOOLBOX_DEFAULT_8BIT_COLORS;
  671. }
  672. imagetruecolortopalette($dummy, $dither, $output_quality);
  673. }
  674. imagepng($dummy, $filename);
  675. imagedestroy($dummy);
  676. }
  677. else {
  678. imagepng($this->_img['main']['resource'], $filename);
  679. }
  680. break;
  681. default:
  682. trigger_error($this->_error_prefix . 'Output-Imagetype not supported.', E_USER_ERROR);
  683. return null;
  684. }
  685. return true;
  686. }
  687. /**
  688. * Sets the resize method of choice
  689. *
  690. * $method can be one of the following:<br>
  691. * <ul>
  692. * <li>'resize' -> supported by every version of GD (fast but ugly resize of image)</li>
  693. * <li>'resample' -> only supported by GD version >= 2.0 (slower but antialiased resize of image)</li>
  694. * <li>'workaround' -> supported by every version of GD (workaround function for bicubic resizing, downsizing, VERY slow!, taken from php.net comments)</li>
  695. * <li>'workaround2' -> supported by every version of GD (alternative workaround function for bicubic resizing, down- and upsizing, VERY VERY slow!, taken from php.net comments)</li>
  696. * </ul>
  697. *
  698. * @param string|integer $method resize method
  699. * @return bool true on success, otherwise false
  700. */
  701. function setResizeMethod($method)
  702. {
  703. switch ($method) {
  704. case 1:
  705. case '1':
  706. case 'resize':
  707. $this->_resize_function = 'imagecopyresized';
  708. break;
  709. case 2:
  710. case '2':
  711. case 'resample':
  712. if (!function_exists('imagecopyresampled')) {
  713. // no error message. just return false.
  714. return null;
  715. }
  716. $this->_resize_function = 'imagecopyresampled';
  717. break;
  718. case 3:
  719. case '3':
  720. case 'resample_workaround':
  721. case 'workaround':
  722. case 'bicubic':
  723. $this->_resize_function = '$this->_imageCopyResampledWorkaround';
  724. break;
  725. case 4:
  726. case '4':
  727. case 'resample_workaround2':
  728. case 'workaround2':
  729. case 'bicubic2':
  730. $this->_resize_function = '$this->_imageCopyResampledWorkaround2';
  731. break;
  732. default:
  733. trigger_error($this->_error_prefix . 'Resizemethod not supported.', E_USER_ERROR);
  734. return null;
  735. }
  736. return true;
  737. }
  738. /**
  739. * Resize the current image
  740. *
  741. * if $width = 0 the new width will be calculated from the $height value preserving the correct aspectratio.<br>
  742. *
  743. * if $height = 0 the new height will be calculated from the $width value preserving the correct aspectratio.<br>
  744. *
  745. * $mode can be one of the following:<br>
  746. * <ul>
  747. * <li>0 -> image will be resized to the new output size, regardless of the original aspectratio. (default)</li>
  748. * <li>1 -> image will be cropped if necessary to preserve the aspectratio and avoid image distortions.</li>
  749. * <li>2 -> image will be resized preserving its original aspectratio. differences to the new outputsize will be filled with $bgcolor</li>
  750. * </ul>
  751. *
  752. * if $autorotate is set to true the given $width and $height values may "change place" if the given image bias is different from the original one.<br>
  753. * if either $width or $height is 0, the new size will be applied to either the new width or the new height based on the bias value of the original image.<br>
  754. * (default = false)
  755. *
  756. * @param integer $width new width of image
  757. * @param integer $height new height of image
  758. * @param integer $mode resize mode
  759. * @param bool $autorotate use autorotating
  760. * @param string $bgcolor background fillcolor (hexformat, e.g. '#FF0000')
  761. * @return bool true on success, otherwise false
  762. */
  763. function newOutputSize($width, $height, $mode = 0, $autorotate = false, $bgcolor = '#000000')
  764. {
  765. if ($width > 0 && $height > 0 && is_int($width) && is_int($height)) {
  766. //ignore aspectratio
  767. if (!$mode) {
  768. //do not crop to get correct aspectratio
  769. ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  770. if ($this->_img['main']['bias'] == $this->_img['target']['bias'] || !$autorotate) {
  771. $this->_img['target']['width'] = $width;
  772. $this->_img['target']['height'] = $height;
  773. } else {
  774. $this->_img['target']['width'] = $height;
  775. $this->_img['target']['height'] = $width;
  776. }
  777. $this->_img['target']['aspectratio'] = $this->_img['target']['width'] / $this->_img['target']['height'];
  778. $cpy_w = $this->_img['main']['width'];
  779. $cpy_h = $this->_img['main']['height'];
  780. $cpy_w_offset = 0;
  781. $cpy_h_offset = 0;
  782. } elseif ($mode == 1) {
  783. //crop to get correct aspectratio
  784. ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  785. if ($this->_img['main']['bias'] == $this->_img['target']['bias'] || !$autorotate) {
  786. $this->_img['target']['width'] = $width;
  787. $this->_img['target']['height'] = $height;
  788. } else {
  789. $this->_img['target']['width'] = $height;
  790. $this->_img['target']['height'] = $width;
  791. }
  792. $this->_img['target']['aspectratio'] = $this->_img['target']['width'] / $this->_img['target']['height'];
  793. if ($this->_img['main']['width'] / $this->_img['target']['width'] >= $this->_img['main']['height'] / $this->_img['target']['height']) {
  794. $cpy_h = $this->_img['main']['height'];
  795. $cpy_w = (integer) $this->_img['main']['height'] * $this->_img['target']['aspectratio'];
  796. $cpy_w_offset = (integer) ($this->_img['main']['width'] - $cpy_w) / 2;
  797. $cpy_h_offset = 0;
  798. } else {
  799. $cpy_w = $this->_img['main']['width'];
  800. $cpy_h = (integer) $this->_img['main']['width'] / $this->_img['target']['aspectratio'];
  801. $cpy_h_offset = (integer) ($this->_img['main']['height'] - $cpy_h) / 2;
  802. $cpy_w_offset = 0;
  803. }
  804. }
  805. elseif ($mode == 2) {
  806. //fill remaining background with a color to keep aspectratio
  807. $final_aspectratio = $width / $height;
  808. if ($final_aspectratio < $this->_img['main']['aspectratio']) {
  809. $this->_img['target']['width'] = $width;
  810. $this->_img['target']['height'] = (integer) $width / $this->_img['main']['aspectratio'];
  811. $cpy_w_offset2 = 0;
  812. $cpy_h_offset2 = (integer) (($height - $this->_img['target']['height']) / 2);
  813. }
  814. else {
  815. $this->_img['target']['height'] = $height;
  816. $this->_img['target']['width'] = (integer) $height * $this->_img['main']['aspectratio'];
  817. $cpy_h_offset2 = 0;
  818. $cpy_w_offset2 = (integer) (($width - $this->_img['target']['width']) / 2);
  819. }
  820. $this->_img['target']['aspectratio'] = $this->_img['main']['aspectratio'];
  821. $cpy_w = $this->_img['main']['width'];
  822. $cpy_h = $this->_img['main']['height'];
  823. $cpy_w_offset = 0;
  824. $cpy_h_offset = 0;
  825. }
  826. } elseif (($width == 0 && $height > 0) || ($width > 0 && $height == 0) && is_int($width) && is_int($height)) {
  827. //keep aspectratio
  828. if ($autorotate == true) {
  829. if ($this->_img['main']['bias'] == IMAGE_TOOLBOX_BIAS_HORIZONTAL && $width > 0) {
  830. $height = $width;
  831. $width = 0;
  832. } elseif ($this->_img['main']['bias'] == IMAGE_TOOLBOX_BIAS_VERTICAL && $height > 0) {
  833. $width = $height;
  834. $height = 0;
  835. }
  836. }
  837. ($width >= $height) ? ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_HORIZONTAL) : ($this->_img['target']['bias'] = IMAGE_TOOLBOX_BIAS_VERTICAL);
  838. if ($width != 0) {
  839. $this->_img['target']['width'] = $width;
  840. $this->_img['target']['height'] = (integer) $width / $this->_img['main']['aspectratio'];
  841. } else {
  842. $this->_img['target']['height'] = $height;
  843. $this->_img['target']['width'] = (integer) $height * $this->_img['main']['aspectratio'];
  844. }
  845. $this->_img['target']['aspectratio'] = $this->_img['main']['aspectratio'];
  846. $cpy_w = $this->_img['main']['width'];
  847. $cpy_h = $this->_img['main']['height'];
  848. $cpy_w_offset = 0;
  849. $cpy_h_offset = 0;
  850. } else {
  851. /*
  852. print ($width == 0 && $height > 0) ? 'yes' : 'no';
  853. print "<br>";
  854. print ($width > 0 && $height == 0) ? 'yes' : 'no';
  855. print "<br>";
  856. print is_int($width) ? 'yes' : 'no';
  857. debug_print_backtrace();
  858. */
  859. trigger_error($this->_error_prefix . 'Outputwidth and -height must be integers greater zero.', E_USER_ERROR);
  860. return null;
  861. }
  862. //create resized picture
  863. $functionname = $this->_imagecreatefunction;
  864. $dummy = $functionname($this->_img['target']['width'] + 1, $this->_img['target']['height'] + 1);
  865. eval($this->_resize_function . '($dummy, $this->_img["main"]["resource"], 0, 0, $cpy_w_offset, $cpy_h_offset, $this->_img["target"]["width"], $this->_img["target"]["height"], $cpy_w, $cpy_h);');
  866. if ($mode == 2) {
  867. $this->_img['target']['resource'] = $functionname($width, $height);
  868. $fillcolor = $this->_hexToPHPColor($bgcolor);
  869. imagefill($this->_img['target']['resource'], 0, 0, $fillcolor);
  870. } else {
  871. $this->_img['target']['resource'] = $functionname($this->_img['target']['width'], $this->_img['target']['height']);
  872. $cpy_w_offset2 = 0;
  873. $cpy_h_offset2 = 0;
  874. }
  875. imagecopy($this->_img['target']['resource'], $dummy, $cpy_w_offset2, $cpy_h_offset2, 0, 0, $this->_img['target']['width'], $this->_img['target']['height']);
  876. imagedestroy($dummy);
  877. if ($mode == 2) {
  878. $this->_img['target']['width'] = $width;
  879. $this->_img['target']['height'] = $height;
  880. }
  881. //update _img['main'] with new data
  882. foreach ($this->_img['target'] as $key => $value) {
  883. $this->_img['main'][$key] = $value;
  884. }
  885. unset ($this->_img['target']);
  886. return true;
  887. }
  888. /**
  889. * Adds a new image resource based on the given parameters.
  890. *
  891. * It does not overwrite the existing image resource.<br>
  892. * Instead it is used to load a second image to merge with the existing image.
  893. *
  894. * Parameter:<br>
  895. * <i>string</i> <b>$file</b> imagefile to load<br>
  896. * Or:<br>
  897. * <i>integer</i> <b>$width</b> imagewidth of new image to be created<br>
  898. * <i>integer</i> <b>$height</b> imageheight of new image to be created<br>
  899. * <i>string</i> <b>$fillcolor</b> optional fill the new image with this color (hexformat, e.g. '#FF0000')<br>
  900. */
  901. function addImage()
  902. {
  903. $args = func_get_args();
  904. $argc = func_num_args();
  905. if ($this->_addImage($argc, $args)) {
  906. return true;
  907. } else {
  908. trigger_error($this->_error_prefix . 'failed to add image.', E_USER_ERROR);
  909. return false;
  910. }
  911. }
  912. /**
  913. * Blend two images.
  914. *
  915. * Original image and the image loaded with {@link addImage() addImage}<br>
  916. * NOTE: This operation can take very long and is not intended for realtime use.
  917. * (but of course depends on the power of your server :))
  918. *
  919. * IMPORTANT: {@link imagecopymerge() imagecopymerged} doesn't work with PHP 4.3.2. Bug ID: {@link http://bugs.php.net/bug.php?id=24816 24816}<br>
  920. *
  921. * $x:<br>
  922. * negative values are possible.<br>
  923. * You can also use the following keywords ('left', 'center' or 'middle', 'right').<br>
  924. * Additionally you can specify an offset in pixel with the keywords like this 'left +10'.<br>
  925. * (default = 0)
  926. *
  927. * $y:<br>
  928. * negative values are possible.<br>
  929. * You can also use the following keywords ('top', 'center' or 'middle', 'bottom').<br>
  930. * Additionally you can specify an offset in pixel with the keywords like this 'bottom -10'.<br>
  931. * (default = 0)
  932. *
  933. * Possible values for $mode:
  934. * <ul>
  935. * <li>IMAGE_TOOLBOX_BLEND_COPY</li>
  936. * <li>IMAGE_TOOLBOX_BLEND_MULTIPLY</li>
  937. * <li>IMAGE_TOOLBOX_BLEND_SCREEN</li>
  938. * <li>IMAGE_TOOLBOX_BLEND_DIFFERENCE</li>
  939. * <li>IMAGE_TOOLBOX_BLEND_EXCLUSION</li>
  940. * <li>IMAGE_TOOLBOX_BLEND_OVERLAY</li>
  941. * </ul>
  942. *
  943. * $percent:<br>
  944. * alpha value in percent of blend effect (0 - 100)<br>
  945. * (default = 100)
  946. *
  947. * @param string|integer $x Horizontal position of second image.
  948. * @param integer $y Vertical position of second image. negative values are possible.
  949. * @param integer $mode blend mode.
  950. * @param integer $percent alpha value
  951. */
  952. function blend($x = 0, $y = 0, $mode = IMAGE_TOOLBOX_BLEND_COPY, $percent = 100)
  953. {
  954. if (is_string($x) || is_string($y)) {
  955. list($xalign, $xalign_offset) = explode(" ", $x);
  956. list($yalign, $yalign_offset) = explode(" ", $y);
  957. }
  958. if (is_string($x)) {
  959. switch ($xalign) {
  960. case 'left':
  961. $dst_x = 0 + $xalign_offset;
  962. $src_x = 0;
  963. $src_w = $this->_img['operator']['width'];
  964. break;
  965. case 'right':
  966. $dst_x = ($this->_img['main']['width'] - $this->_img['operator']['width']) + $xalign_offset;
  967. $src_x = 0;
  968. $src_w = $this->_img['operator']['width'];
  969. break;
  970. case 'middle':
  971. case 'center':
  972. $dst_x = (($this->_img['main']['width'] / 2) - ($this->_img['operator']['width'] / 2)) + $yalign_offset;
  973. $src_x = 0;
  974. $src_w = $this->_img['operator']['width'];
  975. break;
  976. }
  977. } else {
  978. if ($x >= 0) {
  979. $dst_x = $x;
  980. $src_x = 0;
  981. $src_w = $this->_img['operator']['width'];
  982. } else {
  983. $dst_x = 0;
  984. $src_x = abs($x);
  985. $src_w = $this->_img['operator']['width'] - $src_x;
  986. }
  987. }
  988. if (is_string($y)) {
  989. switch ($yalign) {
  990. case 'top':
  991. $dst_y = 0 + $yalign_offset;
  992. $src_y = 0;
  993. $src_h = $this->_img['operator']['height'];
  994. break;
  995. case 'bottom':
  996. $dst_y = ($this->_img['main']['height'] - $this->_img['operator']['height']) + $yalign_offset;
  997. $src_y = 0;
  998. $src_h = $this->_img['operator']['height'];
  999. break;
  1000. case 'middle':
  1001. case 'center':
  1002. $dst_y = (($this->_img['main']['height'] / 2) - ($this->_img['operator']['height'] / 2)) + $yalign_offset;
  1003. $src_y = 0;
  1004. $src_h = $this->_img['operator']['height'];
  1005. break;
  1006. }
  1007. } else {
  1008. if ($y >= 0) {
  1009. $dst_y = $y;
  1010. $src_y = 0;
  1011. $src_h = $this->_img['operator']['height'];
  1012. } else {
  1013. $dst_y = 0;
  1014. $src_y = abs($y);
  1015. $src_h = $this->_img['operator']['height'] - $src_y;
  1016. }
  1017. }
  1018. $this->_imageBlend($mode, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
  1019. return true;
  1020. }
  1021. /**
  1022. * Blend two images.
  1023. *
  1024. * @access private
  1025. */
  1026. function _imageBlend($mode, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent)
  1027. {
  1028. if ($mode == IMAGE_TOOLBOX_BLEND_COPY) {
  1029. if ($percent == 100) {
  1030. imagecopy($this->_img['main']['resource'], $this->_img['operator']['resource'], $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
  1031. } else {
  1032. imagecopymerge($this->_img['main']['resource'], $this->_img['operator']['resource'], $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
  1033. }
  1034. } else {
  1035. $functionname = $this->_imagecreatefunction;
  1036. $dummy = $functionname($src_w, $src_h);
  1037. for ($y=0; $y < $src_h; $y++) {
  1038. for ($x=0; $x < $src_w; $x++) {
  1039. $colorindex = imagecolorat($this->_img['main']['resource'], $dst_x + $x, $dst_y + $y);
  1040. $colorrgb1 = imagecolorsforindex($this->_img['main']['resource'], $colorindex);
  1041. $colorindex = imagecolorat($this->_img['operator']['resource'], $src_x + $x, $src_y + $y);
  1042. $colorrgb2 = imagecolorsforindex($this->_img['operator']['resource'], $colorindex);
  1043. $colorblend = $this->_calculateBlendvalue($mode, $colorrgb1, $colorrgb2);
  1044. $newcolor = imagecolorallocate($dummy, $colorblend['red'], $colorblend['green'], $colorblend['blue']);
  1045. imagesetpixel($dummy, $x, $y, $newcolor);
  1046. }
  1047. }
  1048. $this->_img['target']['resource'] = $functionname($this->_img['main']['width'], $this->_img['main']['height']);
  1049. imagecopy($this->_img['target']['resource'], $this->_img['main']['resource'], 0, 0, 0, 0, $this->_img['main']['width'], $this->_img['main']['height']);
  1050. imagecopymerge($this->_img['target']['resource'], $dummy, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $percent);
  1051. $this->_img['main']['resource'] = $this->_img['target']['resource'];
  1052. unset($this->_img['target']);
  1053. }
  1054. }
  1055. /**
  1056. * Calculate blend values for given blend mode
  1057. *
  1058. * @access private
  1059. */
  1060. function _calculateBlendvalue($mode, $colorrgb1, $colorrgb2)
  1061. {
  1062. switch ($mode) {
  1063. case IMAGE_TOOLBOX_BLEND_MULTIPLY:
  1064. $c['red'] = ($colorrgb1['red'] * $colorrgb2['red']) >> 8;
  1065. $c['green'] = ($colorrgb1['green'] * $colorrgb2['green']) >> 8;
  1066. $c['blue'] = ($colorrgb1['blue'] * $colorrgb2['blue']) >> 8;
  1067. break;
  1068. case IMAGE_TOOLBOX_BLEND_SCREEN:
  1069. $c['red'] = 255 - ((255 - $colorrgb1['red']) * (255 - $colorrgb2['red']) >> 8);
  1070. $c['green'] = 255 - ((255 - $colorrgb1['green']) * (255 - $colorrgb2['green']) >> 8);
  1071. $c['blue'] = 255 - ((255 - $colorrgb1['blue']) * (255 - $colorrgb2['blue']) >> 8);
  1072. break;
  1073. case IMAGE_TOOLBOX_BLEND_DIFFERENCE:
  1074. $c['red'] = abs($colorrgb1['red'] - $colorrgb2['red']);
  1075. $c['green'] = abs($colorrgb1['green'] - $colorrgb2['green']);
  1076. $c['blue'] = abs($colorrgb1['blue'] - $colorrgb2['blue']);
  1077. break;
  1078. case IMAGE_TOOLBOX_BLEND_NEGATION:
  1079. $c['red'] = 255 - abs(255 - $colorrgb1['red'] - $colorrgb2['red']);
  1080. $c['green'] = 255 - abs(255 - $colorrgb1['green'] - $colorrgb2['green']);
  1081. $c['blue'] = 255 - abs(255 - $colorrgb1['blue'] - $colorrgb2['blue']);
  1082. break;
  1083. case IMAGE_TOOLBOX_BLEND_EXCLUTION:

Large files files are truncated, but you can click here to view the full file