[239] | 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 | ?> |
---|