1 | <?php
|
---|
2 |
|
---|
3 | /** This file is part of KCFinder project
|
---|
4 | *
|
---|
5 | * @desc GD extension class
|
---|
6 | * @package KCFinder
|
---|
7 | * @version 2.51
|
---|
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
|
---|
13 | */
|
---|
14 |
|
---|
15 | class gd {
|
---|
16 |
|
---|
17 | /** GD resource
|
---|
18 | * @var resource */
|
---|
19 | protected $image;
|
---|
20 |
|
---|
21 | /** Image width
|
---|
22 | * @var integer */
|
---|
23 | protected $width;
|
---|
24 |
|
---|
25 | /** Image height
|
---|
26 | * @var integer */
|
---|
27 | protected $height;
|
---|
28 |
|
---|
29 | /** Init error
|
---|
30 | * @var bool */
|
---|
31 | public $init_error = false;
|
---|
32 |
|
---|
33 | /** Last builded image type constant (IMAGETYPE_XXX)
|
---|
34 | * @var integer */
|
---|
35 | public $type;
|
---|
36 |
|
---|
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.
|
---|
40 | * @param mixed $image
|
---|
41 | * @return array */
|
---|
42 |
|
---|
43 | protected function build_image($image) {
|
---|
44 |
|
---|
45 | if ($image instanceof gd) {
|
---|
46 | $width = $image->get_width();
|
---|
47 | $height = $image->get_height();
|
---|
48 | $image = $image->get_image();
|
---|
49 |
|
---|
50 | } elseif (is_resource($image) && (get_resource_type($image) == "gd")) {
|
---|
51 | $width = @imagesx($image);
|
---|
52 | $height = @imagesy($image);
|
---|
53 |
|
---|
54 | } elseif (is_array($image)) {
|
---|
55 | list($key, $width) = each($image);
|
---|
56 | list($key, $height) = each($image);
|
---|
57 | $image = imagecreatetruecolor($width, $height);
|
---|
58 |
|
---|
59 | } elseif (false !== (list($width, $height, $type) = @getimagesize($image))) {
|
---|
60 | $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
|
---|
67 | )))));
|
---|
68 |
|
---|
69 | if ($type == IMAGETYPE_PNG)
|
---|
70 | imagealphablending($image, false);
|
---|
71 | }
|
---|
72 |
|
---|
73 | $return = (
|
---|
74 | is_resource($image) &&
|
---|
75 | (get_resource_type($image) == "gd") &&
|
---|
76 | isset($width) &&
|
---|
77 | isset($height) &&
|
---|
78 | (preg_match('/^[1-9][0-9]*$/', $width) !== false) &&
|
---|
79 | (preg_match('/^[1-9][0-9]*$/', $height) !== false)
|
---|
80 | )
|
---|
81 | ? array($image, $width, $height)
|
---|
82 | : false;
|
---|
83 |
|
---|
84 | if (($return !== false) && isset($type))
|
---|
85 | $this->type = $type;
|
---|
86 |
|
---|
87 | return $return;
|
---|
88 | }
|
---|
89 |
|
---|
90 | /** Parameter $image can be:
|
---|
91 | * 1. An instance of this class (copy instance).
|
---|
92 | * 2. A GD resource.
|
---|
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
|
---|
97 | * @param mixed $image
|
---|
98 | * @param integer $bigger_size
|
---|
99 | * @return gd */
|
---|
100 |
|
---|
101 | public function __construct($image, $bigger_size=null) {
|
---|
102 | $this->image = $this->width = $this->height = null;
|
---|
103 |
|
---|
104 | $image_details = $this->build_image($image);
|
---|
105 |
|
---|
106 | if ($image_details !== false)
|
---|
107 | list($this->image, $this->width, $this->height) = $image_details;
|
---|
108 | else
|
---|
109 | $this->init_error = true;
|
---|
110 |
|
---|
111 | if (!is_null($this->image) &&
|
---|
112 | !is_null($bigger_size) &&
|
---|
113 | (preg_match('/^[1-9][0-9]*$/', $bigger_size) !== false)
|
---|
114 | ) {
|
---|
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);
|
---|
121 | }
|
---|
122 | $this->width = $width;
|
---|
123 | $this->height = $height;
|
---|
124 | $this->imagecopyresampled($image);
|
---|
125 | }
|
---|
126 | }
|
---|
127 |
|
---|
128 | /** Returns the GD resource
|
---|
129 | * @return resource */
|
---|
130 |
|
---|
131 | public function get_image() {
|
---|
132 | return $this->image;
|
---|
133 | }
|
---|
134 |
|
---|
135 | /** Returns the image width
|
---|
136 | * @return integer */
|
---|
137 |
|
---|
138 | public function get_width() {
|
---|
139 | return $this->width;
|
---|
140 | }
|
---|
141 |
|
---|
142 | /** Returns the image height
|
---|
143 | * @return integer */
|
---|
144 |
|
---|
145 | public function get_height() {
|
---|
146 | return $this->height;
|
---|
147 | }
|
---|
148 |
|
---|
149 | /** Returns calculated proportional width from the given height
|
---|
150 | * @param integer $resized_height
|
---|
151 | * @return integer */
|
---|
152 |
|
---|
153 | public function get_prop_width($resized_height) {
|
---|
154 | $width = intval(($this->width * $resized_height) / $this->height);
|
---|
155 | if (!$width) $width = 1;
|
---|
156 | return $width;
|
---|
157 | }
|
---|
158 |
|
---|
159 | /** Returns calculated proportional height from the given width
|
---|
160 | * @param integer $resized_width
|
---|
161 | * @return integer */
|
---|
162 |
|
---|
163 | public function get_prop_height($resized_width) {
|
---|
164 | $height = intval(($this->height * $resized_width) / $this->width);
|
---|
165 | if (!$height) $height = 1;
|
---|
166 | return $height;
|
---|
167 | }
|
---|
168 |
|
---|
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
|
---|
173 | * @return array */
|
---|
174 |
|
---|
175 | public function get_prop_size($bigger_size) {
|
---|
176 |
|
---|
177 | if ($this->width > $this->height) {
|
---|
178 | $width = $bigger_size;
|
---|
179 | $height = $this->get_prop_height($width);
|
---|
180 |
|
---|
181 | } elseif ($this->height > $this->width) {
|
---|
182 | $height = $bigger_size;
|
---|
183 | $width = $this->get_prop_width($height);
|
---|
184 |
|
---|
185 | } else
|
---|
186 | $width = $height = $bigger_size;
|
---|
187 |
|
---|
188 | return array($width, $height);
|
---|
189 | }
|
---|
190 |
|
---|
191 | /** Resize image. Returns TRUE on success or FALSE on failure
|
---|
192 | * @param integer $width
|
---|
193 | * @param integer $height
|
---|
194 | * @return bool */
|
---|
195 |
|
---|
196 | public function resize($width, $height) {
|
---|
197 | if (!$width) $width = 1;
|
---|
198 | if (!$height) $height = 1;
|
---|
199 | return (
|
---|
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()))
|
---|
205 | );
|
---|
206 | }
|
---|
207 |
|
---|
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
|
---|
210 | * @param mixed $src
|
---|
211 | * @return bool */
|
---|
212 |
|
---|
213 | public function resize_crop($src) {
|
---|
214 | $image_details = $this->build_image($src);
|
---|
215 |
|
---|
216 | if ($image_details !== false) {
|
---|
217 | list($src, $src_width, $src_height) = $image_details;
|
---|
218 |
|
---|
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);
|
---|
223 | $src_y = 0;
|
---|
224 |
|
---|
225 | } else {
|
---|
226 | $src_w = $src_width;
|
---|
227 | $src_h = $this->get_prop_height($src_width);
|
---|
228 | $src_x = 0;
|
---|
229 | $src_y = intval(($src_height - $src_h) / 2);
|
---|
230 | }
|
---|
231 |
|
---|
232 | return imagecopyresampled($this->image, $src, 0, 0, $src_x, $src_y, $this->width, $this->height, $src_w, $src_h);
|
---|
233 |
|
---|
234 | } else
|
---|
235 | return false;
|
---|
236 | }
|
---|
237 |
|
---|
238 | /** Resize image to fit in given resolution. Returns TRUE on success or FALSE on failure
|
---|
239 | * @param integer $width
|
---|
240 | * @param integer $height
|
---|
241 | * @return bool */
|
---|
242 |
|
---|
243 | public function resize_fit($width, $height) {
|
---|
244 | if ((!$width && !$height) || (($width == $this->width) && ($height == $this->height)))
|
---|
245 | return true;
|
---|
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);
|
---|
253 | }
|
---|
254 |
|
---|
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
|
---|
260 | * @return bool */
|
---|
261 |
|
---|
262 | public function resize_overflow($width, $height) {
|
---|
263 |
|
---|
264 | $big = (($this->width / $this->height) > ($width / $height))
|
---|
265 | ? ($this->width * $height) / $this->height
|
---|
266 | : ($this->height * $width) / $this->width;
|
---|
267 | $big = intval($big);
|
---|
268 |
|
---|
269 | $return = ($img = new gd($this->image, $big));
|
---|
270 |
|
---|
271 | if ($return) {
|
---|
272 | $this->image = $img->get_image();
|
---|
273 | $this->width = $img->get_width();
|
---|
274 | $this->height = $img->get_height();
|
---|
275 | }
|
---|
276 |
|
---|
277 | return $return;
|
---|
278 | }
|
---|
279 |
|
---|
280 | public function gd_color() {
|
---|
281 | $args = func_get_args();
|
---|
282 |
|
---|
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])$/';
|
---|
287 |
|
---|
288 | if (!isset($args[0]))
|
---|
289 | return false;
|
---|
290 |
|
---|
291 | if (count($args[0]) == 3) {
|
---|
292 | list($r, $g, $b) = $args[0];
|
---|
293 |
|
---|
294 | } elseif (preg_match($expr_rgb, $args[0])) {
|
---|
295 | list($r, $g, $b) = explode(" ", preg_replace($expr_rgb, "$1 $2 $3", $args[0]));
|
---|
296 |
|
---|
297 | } elseif (preg_match($expr_hex1, $args[0])) {
|
---|
298 | list($r, $g, $b) = explode(" ", preg_replace($expr_hex1, "$1 $2 $3", $args[0]));
|
---|
299 | $r = hexdec($r);
|
---|
300 | $g = hexdec($g);
|
---|
301 | $b = hexdec($b);
|
---|
302 |
|
---|
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]));
|
---|
305 | $r = hexdec($r);
|
---|
306 | $g = hexdec($g);
|
---|
307 | $b = hexdec($b);
|
---|
308 |
|
---|
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])
|
---|
313 | ) {
|
---|
314 | list($r, $g, $b) = $args;
|
---|
315 |
|
---|
316 | } else
|
---|
317 | return false;
|
---|
318 |
|
---|
319 | return imagecolorallocate($this->image, $r, $g, $b);
|
---|
320 | }
|
---|
321 |
|
---|
322 | public function fill_color($color) {
|
---|
323 | return $this->imagefilledrectangle(0, 0, $this->width - 1, $this->height - 1, $color);
|
---|
324 | }
|
---|
325 |
|
---|
326 |
|
---|
327 | /* G D M E T H O D S */
|
---|
328 |
|
---|
329 | public function imagecopy(
|
---|
330 | $src,
|
---|
331 | $dst_x=0, $dst_y=0,
|
---|
332 | $src_x=0, $src_y=0,
|
---|
333 | $dst_w=null, $dst_h=null,
|
---|
334 | $src_w=null, $src_h=null
|
---|
335 | ) {
|
---|
336 | $image_details = $this->build_image($src);
|
---|
337 |
|
---|
338 | if ($image_details !== false) {
|
---|
339 | list($src, $src_width, $src_height) = $image_details;
|
---|
340 |
|
---|
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);
|
---|
346 |
|
---|
347 | } else
|
---|
348 | return false;
|
---|
349 | }
|
---|
350 |
|
---|
351 | public function imagecopyresampled(
|
---|
352 | $src,
|
---|
353 | $dst_x=0, $dst_y=0,
|
---|
354 | $src_x=0, $src_y=0,
|
---|
355 | $dst_w=null, $dst_h=null,
|
---|
356 | $src_w=null, $src_h=null
|
---|
357 | ) {
|
---|
358 | $image_details = $this->build_image($src);
|
---|
359 |
|
---|
360 | if ($image_details !== false) {
|
---|
361 | list($src, $src_width, $src_height) = $image_details;
|
---|
362 |
|
---|
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);
|
---|
368 |
|
---|
369 | } else
|
---|
370 | return false;
|
---|
371 | }
|
---|
372 |
|
---|
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);
|
---|
377 | }
|
---|
378 |
|
---|
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);
|
---|
384 | }
|
---|
385 |
|
---|
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);
|
---|
390 | }
|
---|
391 |
|
---|
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);
|
---|
396 | }
|
---|
397 | }
|
---|
398 |
|
---|
399 | ?>
|
---|