3 /** This file is part of KCFinder project
5 * @desc GD extension class
8 * @author Pavel Tzonkov <pavelc@users.sourceforge.net>
9 * @copyright 2010, 2011 KCFinder Project
10 * @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2
11 * @license http://www.opensource.org/licenses/lgpl-2.1.php LGPLv2
12 * @link http://kcfinder.sunhater.com
31 public $init_error = false;
33 /** Last builded image type constant (IMAGETYPE_XXX)
37 /** Returns an array. Element 0 - GD resource. Element 1 - width. Element 2 - height.
38 * Returns FALSE on failure. The only one parameter $image can be an instance of this class,
39 * a GD resource, an array(width, height) or path to image file.
43 protected function build_image($image) {
45 if ($image instanceof gd) {
46 $width = $image->get_width();
47 $height = $image->get_height();
48 $image = $image->get_image();
50 } elseif (is_resource($image) && (get_resource_type($image) == "gd")) {
51 $width = @imagesx($image);
52 $height = @imagesy($image);
54 } elseif (is_array($image)) {
55 list($key, $width) = each($image);
56 list($key, $height) = each($image);
57 $image = imagecreatetruecolor($width, $height);
59 } elseif (false !== (list($width, $height, $type) = @getimagesize($image))) {
61 ($type == IMAGETYPE_GIF) ? @imagecreatefromgif($image) : (
62 ($type == IMAGETYPE_WBMP) ? @imagecreatefromwbmp($image) : (
63 ($type == IMAGETYPE_JPEG) ? @imagecreatefromjpeg($image) : (
64 ($type == IMAGETYPE_JPEG2000) ? @imagecreatefromjpeg($image) : (
65 ($type == IMAGETYPE_PNG) ? imagecreatefrompng($image) : (
66 ($type == IMAGETYPE_XBM) ? @imagecreatefromxbm($image) : false
69 if ($type == IMAGETYPE_PNG)
70 imagealphablending($image, false);
74 is_resource($image) &&
75 (get_resource_type($image) == "gd") &&
78 (preg_match('/^[1-9][0-9]*$/', $width) !== false) &&
79 (preg_match('/^[1-9][0-9]*$/', $height) !== false)
81 ? array($image, $width, $height)
84 if (($return !== false) && isset($type))
90 /** Parameter $image can be:
91 * 1. An instance of this class (copy instance).
93 * 3. An array with two elements. First - width, second - height. Create a blank image.
94 * 4. A filename string. Get image form file.
95 * The non-required parameter $bigger_size is the bigger dimension (width or height) the image
96 * will be resized to. The other dimension (height or width) will be calculated autamaticaly
98 * @param integer $bigger_size
101 public function __construct($image, $bigger_size=null) {
102 $this->image = $this->width = $this->height = null;
104 $image_details = $this->build_image($image);
106 if ($image_details !== false)
107 list($this->image, $this->width, $this->height) = $image_details;
109 $this->init_error = true;
111 if (!is_null($this->image) &&
112 !is_null($bigger_size) &&
113 (preg_match('/^[1-9][0-9]*$/', $bigger_size) !== false)
115 $image = $this->image;
116 list($width, $height) = $this->get_prop_size($bigger_size);
117 $this->image = imagecreatetruecolor($width, $height);
118 if ($this->type == IMAGETYPE_PNG) {
119 imagealphablending($this->image, false);
120 imagesavealpha($this->image, true);
122 $this->width = $width;
123 $this->height = $height;
124 $this->imagecopyresampled($image);
128 /** Returns the GD resource
129 * @return resource */
131 public function get_image() {
135 /** Returns the image width
138 public function get_width() {
142 /** Returns the image height
145 public function get_height() {
146 return $this->height;
149 /** Returns calculated proportional width from the given height
150 * @param integer $resized_height
153 public function get_prop_width($resized_height) {
154 $width = intval(($this->width * $resized_height) / $this->height);
155 if (!$width) $width = 1;
159 /** Returns calculated proportional height from the given width
160 * @param integer $resized_width
163 public function get_prop_height($resized_width) {
164 $height = intval(($this->height * $resized_width) / $this->width);
165 if (!$height) $height = 1;
169 /** Returns an array with calculated proportional width & height.
170 * The parameter $bigger_size is the bigger dimension (width or height) of calculated sizes.
171 * The other dimension (height or width) will be calculated autamaticaly
172 * @param integer $bigger_size
175 public function get_prop_size($bigger_size) {
177 if ($this->width > $this->height) {
178 $width = $bigger_size;
179 $height = $this->get_prop_height($width);
181 } elseif ($this->height > $this->width) {
182 $height = $bigger_size;
183 $width = $this->get_prop_width($height);
186 $width = $height = $bigger_size;
188 return array($width, $height);
191 /** Resize image. Returns TRUE on success or FALSE on failure
192 * @param integer $width
193 * @param integer $height
196 public function resize($width, $height) {
197 if (!$width) $width = 1;
198 if (!$height) $height = 1;
200 (false !== ($img = new gd(array($width, $height)))) &&
201 $img->imagecopyresampled($this) &&
202 (false !== ($this->image = $img->get_image())) &&
203 (false !== ($this->width = $img->get_width())) &&
204 (false !== ($this->height = $img->get_height()))
208 /** Resize the given image source (GD, gd object or image file path) to fit in the own image.
209 * The outside ares will be cropped out. Returns TRUE on success or FALSE on failure
213 public function resize_crop($src) {
214 $image_details = $this->build_image($src);
216 if ($image_details !== false) {
217 list($src, $src_width, $src_height) = $image_details;
219 if (($src_width / $src_height) > ($this->width / $this->height)) {
220 $src_w = $this->get_prop_width($src_height);
221 $src_h = $src_height;
222 $src_x = intval(($src_width - $src_w) / 2);
227 $src_h = $this->get_prop_height($src_width);
229 $src_y = intval(($src_height - $src_h) / 2);
232 return imagecopyresampled($this->image, $src, 0, 0, $src_x, $src_y, $this->width, $this->height, $src_w, $src_h);
238 /** Resize image to fit in given resolution. Returns TRUE on success or FALSE on failure
239 * @param integer $width
240 * @param integer $height
243 public function resize_fit($width, $height) {
244 if ((!$width && !$height) || (($width == $this->width) && ($height == $this->height)))
246 if (!$width || (($height / $width) < ($this->height / $this->width)))
247 $width = intval(($this->width * $height) / $this->height);
248 elseif (!$height || (($width / $height) < ($this->width / $this->height)))
249 $height = intval(($this->height * $width) / $this->width);
250 if (!$width) $width = 1;
251 if (!$height) $height = 1;
252 return $this->resize($width, $height);
255 /** Neka si predstavim vyobrazhaem pravoygylnik s razmeri $width i $height.
256 * Izobrazhenieto shte se preorazmeri taka che to shte izliza ot tozi pravoygylnik,
257 * no samo po edno (x ili y) izmerenie
258 * @param integer $width
259 * @param integer $height
262 public function resize_overflow($width, $height) {
264 $big = (($this->width / $this->height) > ($width / $height))
265 ? ($this->width * $height) / $this->height
266 : ($this->height * $width) / $this->width;
269 $return = ($img = new gd($this->image, $big));
272 $this->image = $img->get_image();
273 $this->width = $img->get_width();
274 $this->height = $img->get_height();
280 public function gd_color() {
281 $args = func_get_args();
283 $expr_rgb = '/^rgb\(\s*(\d{1,3})\s*\,\s*(\d{1,3})\s*\,\s*(\d{1,3})\s*\)$/i';
284 $expr_hex1 = '/^\#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i';
285 $expr_hex2 = '/^\#?([0-9a-f])([0-9a-f])([0-9a-f])$/i';
286 $expr_byte = '/^([01]?\d?\d|2[0-4]\d|25[0-5])$/';
288 if (!isset($args[0]))
291 if (count($args[0]) == 3) {
292 list($r, $g, $b) = $args[0];
294 } elseif (preg_match($expr_rgb, $args[0])) {
295 list($r, $g, $b) = explode(" ", preg_replace($expr_rgb, "$1 $2 $3", $args[0]));
297 } elseif (preg_match($expr_hex1, $args[0])) {
298 list($r, $g, $b) = explode(" ", preg_replace($expr_hex1, "$1 $2 $3", $args[0]));
303 } elseif (preg_match($expr_hex2, $args[0])) {
304 list($r, $g, $b) = explode(" ", preg_replace($expr_hex2, "$1$1 $2$2 $3$3", $args[0]));
309 } elseif ((count($args) == 3) &&
310 preg_match($expr_byte, $args[0]) &&
311 preg_match($expr_byte, $args[1]) &&
312 preg_match($expr_byte, $args[2])
314 list($r, $g, $b) = $args;
319 return imagecolorallocate($this->image, $r, $g, $b);
322 public function fill_color($color) {
323 return $this->imagefilledrectangle(0, 0, $this->width - 1, $this->height - 1, $color);
327 /* G D M E T H O D S */
329 public function imagecopy(
333 $dst_w=null, $dst_h=null,
334 $src_w=null, $src_h=null
336 $image_details = $this->build_image($src);
338 if ($image_details !== false) {
339 list($src, $src_width, $src_height) = $image_details;
341 if (is_null($dst_w)) $dst_w = $this->width - $dst_x;
342 if (is_null($dst_h)) $dst_h = $this->height - $dst_y;
343 if (is_null($src_w)) $src_w = $src_width - $src_x;
344 if (is_null($src_h)) $src_h = $src_height - $src_y;
345 return imagecopy($this->image, $src, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
351 public function imagecopyresampled(
355 $dst_w=null, $dst_h=null,
356 $src_w=null, $src_h=null
358 $image_details = $this->build_image($src);
360 if ($image_details !== false) {
361 list($src, $src_width, $src_height) = $image_details;
363 if (is_null($dst_w)) $dst_w = $this->width - $dst_x;
364 if (is_null($dst_h)) $dst_h = $this->height - $dst_y;
365 if (is_null($src_w)) $src_w = $src_width - $src_x;
366 if (is_null($src_h)) $src_h = $src_height - $src_y;
367 return imagecopyresampled($this->image, $src, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
373 public function imagefilledrectangle($x1, $y1, $x2, $y2, $color) {
374 $color = $this->gd_color($color);
375 if ($color === false) return false;
376 return imagefilledrectangle($this->image, $x1, $y1, $x2, $y2, $color);
379 public function imagepng($filename=null, $quality=null, $filters=null) {
380 if (is_null($filename) && !headers_sent())
381 header("Content-Type: image/png");
382 @imagesavealpha($this->image, true);
383 return imagepng($this->image, $filename, $quality, $filters);
386 public function imagejpeg($filename=null, $quality=75) {
387 if (is_null($filename) && !headers_sent())
388 header("Content-Type: image/jpeg");
389 return imagejpeg($this->image, $filename, $quality);
392 public function imagegif($filename=null) {
393 if (is_null($filename) && !headers_sent())
394 header("Content-Type: image/gif");
395 return imagegif($this->image, $filename);