blob: 24695049c078a2c591ae5272cc564ca82a3bd9cc [file] [log] [blame]
Andrey Andreeva92b9032011-12-24 19:05:58 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Eric Barnesb1673362011-12-05 22:05:38 -05008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Eric Barnesb1673362011-12-05 22:05:38 -050010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
Andrey Andreeva3d19c42012-01-24 15:29:29 +020012 * bundled with this package in the files license.txt / license.rst. It is
Derek Jonesf4a4bd82011-10-20 12:18:42 -050013 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * Image Manipulation class
30 *
31 * @package CodeIgniter
32 * @subpackage Libraries
33 * @category Image_lib
Derek Jonesf4a4bd82011-10-20 12:18:42 -050034 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000035 * @link http://codeigniter.com/user_guide/libraries/image_lib.html
36 */
37class CI_Image_lib {
38
Timothy Warrenb8e62852012-04-26 18:40:54 -040039 /**
40 * PHP extension/library to use for image manipulation
41 * Can be: imagemagick, netpbm, gd, gd2
42 *
43 * @var string
44 */
45 public $image_library = 'gd2';
46
47 /**
48 * Path to the graphic library (if applicable)
49 *
50 * @var string
51 */
Andrey Andreev3a459572011-12-21 11:23:11 +020052 public $library_path = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040053
54 /**
55 * Whether to send to browser or write to disk
56 *
57 * @var bool
58 */
59 public $dynamic_output = FALSE;
60
61 /**
62 * Path to original image
63 *
64 * @var string
65 */
Andrey Andreev3a459572011-12-21 11:23:11 +020066 public $source_image = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040067
68 /**
69 * Path to the modified image
70 *
71 * @var string
72 */
Andrey Andreev3a459572011-12-21 11:23:11 +020073 public $new_image = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040074
75 /**
76 * Image width
77 *
78 * @var int
79 */
Andrey Andreev3a459572011-12-21 11:23:11 +020080 public $width = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040081
82 /**
83 * Image height
84 *
85 * @var int
86 */
Andrey Andreev3a459572011-12-21 11:23:11 +020087 public $height = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040088
89 /**
90 * Quality percentage of new image
91 *
92 * @var int
93 */
Andrey Andreev3a459572011-12-21 11:23:11 +020094 public $quality = '90';
Timothy Warrenb8e62852012-04-26 18:40:54 -040095
96 /**
97 * Whether to create a thumbnail
98 *
99 * @var bool
100 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200101 public $create_thumb = FALSE;
Timothy Warrenb8e62852012-04-26 18:40:54 -0400102
103 /**
104 * String to add to thumbnail version of image
105 *
106 * @var string
107 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200108 public $thumb_marker = '_thumb';
Timothy Warrenb8e62852012-04-26 18:40:54 -0400109
110 /**
111 * Whether to maintain aspect ratio when resizing or use hard values
112 *
113 * @var bool
114 */
115 public $maintain_ratio = TRUE;
116
117 /**
118 * auto, height, or width. Determines what to use as the master dimension
119 *
120 * @var string
121 */
122 public $master_dim = 'auto';
123
124 /**
125 * Angle at to rotate image
126 *
127 * @var string
128 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200129 public $rotation_angle = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -0400130
131 /**
132 * X Coordinate for manipulation of the current image
133 *
134 * @var int
135 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200136 public $x_axis = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -0400137
138 /**
139 * Y Coordinate for manipulation of the current image
140 *
141 * @var int
142 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200143 public $y_axis = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000144
Timothy Warrenb8e62852012-04-26 18:40:54 -0400145 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 // Watermark Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400147 // --------------------------------------------------------------------------
148
149 /**
150 * Watermark text if graphic is not used
151 *
152 * @var string
153 */
154 public $wm_text = '';
155
156 /**
157 * Type of watermarking. Options: text/overlay
158 *
159 * @var string
160 */
161 public $wm_type = 'text';
162
163 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400164 * Default transparency for watermark
165 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400166 * @var int
167 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200168 public $wm_x_transp = 4;
Timothy Warrenb8e62852012-04-26 18:40:54 -0400169
170 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400171 * Default transparency for watermark
172 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400173 * @var int
174 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200175 public $wm_y_transp = 4;
Timothy Warrenb8e62852012-04-26 18:40:54 -0400176
177 /**
178 * Watermark image path
179 *
180 * @var string
181 */
182 public $wm_overlay_path = '';
183
184 /**
185 * TT font
186 *
187 * @var string
188 */
189 public $wm_font_path = '';
190
191 /**
192 * Font size (different versions of GD will either use points or pixels)
193 *
194 * @var int
195 */
196 public $wm_font_size = 17;
197
198 /**
199 * Vertical alignment: T M B
200 *
201 * @var string
202 */
203 public $wm_vrt_alignment = 'B';
204
205 /**
206 * Horizontal alignment: L R C
207 *
208 * @var string
209 */
210 public $wm_hor_alignment = 'C';
211
212 /**
213 * Padding around text
214 *
215 * @var int
216 */
217 public $wm_padding = 0;
218
219 /**
220 * Lets you push text to the right
221 *
222 * @var int
223 */
224 public $wm_hor_offset = 0;
225
226 /**
227 * Lets you push text down
228 *
229 * @var int
230 */
231 public $wm_vrt_offset = 0;
232
233 /**
234 * Text color
235 *
236 * @var string
237 */
238 protected $wm_font_color = '#ffffff';
239
240 /**
241 * Dropshadow color
242 *
243 * @var string
244 */
245 protected $wm_shadow_color = '';
246
247 /**
248 * Dropshadow distance
249 *
250 * @var int
251 */
252 public $wm_shadow_distance = 2;
253
254 /**
255 * Image opacity: 1 - 100 Only works with image
256 *
257 * @var int
258 */
259 public $wm_opacity = 50;
Derek Allard2067d1a2008-11-13 22:59:24 +0000260
Timothy Warrenb8e62852012-04-26 18:40:54 -0400261 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 // Private Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400263 // --------------------------------------------------------------------------
264
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400265 /**
266 * Source image folder
267 *
268 * @var string
269 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200270 public $source_folder = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400271
272 /**
273 * Destination image folder
274 *
275 * @var string
276 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200277 public $dest_folder = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400278
279 /**
280 * Image mime-type
281 *
282 * @var string
283 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200284 public $mime_type = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400285
286 /**
287 * Original image width
288 *
289 * @var int
290 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200291 public $orig_width = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400292
293 /**
294 * Original image height
295 *
296 * @var int
297 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200298 public $orig_height = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400299
300 /**
301 * Image format
302 *
303 * @var string
304 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200305 public $image_type = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400306
307 /**
308 * Size of current image
309 *
310 * @var string
311 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200312 public $size_str = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400313
314 /**
315 * Full path to source image
316 *
317 * @var string
318 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200319 public $full_src_path = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400320
321 /**
322 * Full path to destination image
323 *
324 * @var string
325 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200326 public $full_dst_path = '';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400327
328 /**
329 * Name of function to create image
330 *
331 * @var string
332 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200333 public $create_fnc = 'imagecreatetruecolor';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400334
335 /**
336 * Name of function to copy image
337 *
338 * @var string
339 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200340 public $copy_fnc = 'imagecopyresampled';
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400341
342 /**
343 * Error messages
344 *
345 * @var array
346 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200347 public $error_msg = array();
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400348
349 /**
350 * Whether to have a drop shadow on watermark
351 *
352 * @var bool
353 */
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200354 protected $wm_use_drop_shadow = FALSE;
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400355
356 /**
357 * Whether to use truetype fonts
358 *
359 * @var bool
360 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200361 public $wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000362
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400363 /**
364 * Initialize Image Library
365 *
366 * @param array $props
367 */
Greg Akera9263282010-11-10 15:26:43 -0600368 public function __construct($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 {
370 if (count($props) > 0)
371 {
372 $this->initialize($props);
373 }
374
Andrey Andreev8e70b792012-01-12 20:19:24 +0200375 log_message('debug', 'Image Lib Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 }
377
378 // --------------------------------------------------------------------
379
380 /**
381 * Initialize image properties
382 *
383 * Resets values in case this class is used in a loop
384 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 * @return void
386 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200387 public function clear()
Derek Allard2067d1a2008-11-13 22:59:24 +0000388 {
Michael Denniscb07a322011-08-20 23:40:59 -0700389 $props = array('library_path', 'source_image', 'new_image', 'width', 'height', 'rotation_angle', 'x_axis', 'y_axis', 'wm_text', 'wm_overlay_path', 'wm_font_path', 'wm_shadow_color', 'source_folder', 'dest_folder', 'mime_type', 'orig_width', 'orig_height', 'image_type', 'size_str', 'full_src_path', 'full_dst_path');
Derek Allard2067d1a2008-11-13 22:59:24 +0000390
391 foreach ($props as $val)
392 {
393 $this->$val = '';
394 }
395
Michael Denniscb07a322011-08-20 23:40:59 -0700396 $this->image_library = 'gd2';
397 $this->dynamic_output = FALSE;
398 $this->quality = '90';
399 $this->create_thumb = FALSE;
400 $this->thumb_marker = '_thumb';
401 $this->maintain_ratio = TRUE;
402 $this->master_dim = 'auto';
403 $this->wm_type = 'text';
404 $this->wm_x_transp = 4;
405 $this->wm_y_transp = 4;
406 $this->wm_font_size = 17;
407 $this->wm_vrt_alignment = 'B';
408 $this->wm_hor_alignment = 'C';
409 $this->wm_padding = 0;
410 $this->wm_hor_offset = 0;
411 $this->wm_vrt_offset = 0;
412 $this->wm_font_color = '#ffffff';
413 $this->wm_shadow_distance = 2;
414 $this->wm_opacity = 50;
415 $this->create_fnc = 'imagecreatetruecolor';
416 $this->copy_fnc = 'imagecopyresampled';
417 $this->error_msg = array();
418 $this->wm_use_drop_shadow = FALSE;
419 $this->wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000420 }
421
422 // --------------------------------------------------------------------
423
424 /**
425 * initialize image preferences
426 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000427 * @param array
428 * @return bool
429 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200430 public function initialize($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000431 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200432 // Convert array elements into class variables
Derek Allard2067d1a2008-11-13 22:59:24 +0000433 if (count($props) > 0)
434 {
435 foreach ($props as $key => $val)
436 {
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200437 if (property_exists($this, $key))
438 {
439 if (in_array($key, array('wm_font_color', 'wm_shadow_color')))
440 {
Andrey Andreev8323ae62011-12-31 18:39:10 +0200441 if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200442 {
Andrey Andreevcf2ba9e2012-01-01 21:57:13 +0200443 /* $matches[1] contains our hex color value, but it might be
Andrey Andreev8323ae62011-12-31 18:39:10 +0200444 * both in the full 6-length format or the shortened 3-length
445 * value.
Andrey Andreevbb96c8b2011-12-31 18:48:39 +0200446 * We'll later need the full version, so we keep it if it's
Andrey Andreev8323ae62011-12-31 18:39:10 +0200447 * already there and if not - we'll convert to it. We can
448 * access string characters by their index as in an array,
449 * so we'll do that and use concatenation to form the final
450 * value:
451 */
Andrey Andreev665af0c2011-12-30 14:39:29 +0200452 $val = (strlen($matches[1]) === 6)
453 ? '#'.$matches[1]
454 : '#'.$matches[1][0].$matches[1][0].$matches[1][1].$matches[1][1].$matches[1][2].$matches[1][2];
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200455 }
456 else
457 {
458 continue;
459 }
460 }
461
462 $this->$key = $val;
463 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 }
465 }
466
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200467 // Is there a source image? If not, there's no reason to continue
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 if ($this->source_image == '')
469 {
470 $this->set_error('imglib_source_image_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500471 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000472 }
473
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200474 /* Is getimagesize() available?
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 *
476 * We use it to determine the image properties (width/height).
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200477 * Note: We need to figure out how to determine image
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 * properties using ImageMagick and NetPBM
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 */
480 if ( ! function_exists('getimagesize'))
481 {
482 $this->set_error('imglib_gd_required_for_props');
483 return FALSE;
484 }
485
486 $this->image_library = strtolower($this->image_library);
487
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200488 /* Set the full server path
Derek Allard2067d1a2008-11-13 22:59:24 +0000489 *
490 * The source image may or may not contain a path.
491 * Either way, we'll try use realpath to generate the
492 * full server path in order to more reliably read it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200494 if (function_exists('realpath') && @realpath($this->source_image) !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200496 $full_source_path = str_replace('\\', '/', realpath($this->source_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 }
498 else
499 {
500 $full_source_path = $this->source_image;
501 }
502
503 $x = explode('/', $full_source_path);
504 $this->source_image = end($x);
505 $this->source_folder = str_replace($this->source_image, '', $full_source_path);
506
507 // Set the Image Properties
508 if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
509 {
Eric Barnesb1673362011-12-05 22:05:38 -0500510 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000511 }
512
513 /*
514 * Assign the "new" image name/path
515 *
516 * If the user has set a "new_image" name it means
517 * we are making a copy of the source image. If not
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200518 * it means we are altering the original. We'll
Derek Allard2067d1a2008-11-13 22:59:24 +0000519 * set the destination filename and path accordingly.
Derek Allard2067d1a2008-11-13 22:59:24 +0000520 */
521 if ($this->new_image == '')
522 {
523 $this->dest_image = $this->source_image;
524 $this->dest_folder = $this->source_folder;
525 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200526 elseif (strpos($this->new_image, '/') === FALSE)
527 {
528 $this->dest_folder = $this->source_folder;
529 $this->dest_image = $this->new_image;
530 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000531 else
532 {
Andrey Andreev1b815532012-04-03 16:06:03 +0300533 if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200535 $full_dest_path = str_replace('\\', '/', realpath($this->new_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000536 }
537 else
538 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200539 $full_dest_path = $this->new_image;
540 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000541
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200542 // Is there a file name?
543 if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path))
544 {
545 $this->dest_folder = $full_dest_path.'/';
546 $this->dest_image = $this->source_image;
547 }
548 else
549 {
550 $x = explode('/', $full_dest_path);
551 $this->dest_image = end($x);
552 $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 }
554 }
555
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200556 /* Compile the finalized filenames/paths
Derek Allard2067d1a2008-11-13 22:59:24 +0000557 *
558 * We'll create two master strings containing the
559 * full server path to the source image and the
560 * full server path to the destination image.
561 * We'll also split the destination image name
562 * so we can insert the thumbnail marker if needed.
Derek Allard2067d1a2008-11-13 22:59:24 +0000563 */
564 if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
565 {
566 $this->thumb_marker = '';
567 }
568
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200569 $xp = $this->explode_name($this->dest_image);
Derek Allard2067d1a2008-11-13 22:59:24 +0000570
571 $filename = $xp['name'];
572 $file_ext = $xp['ext'];
573
574 $this->full_src_path = $this->source_folder.$this->source_image;
575 $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
576
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200577 /* Should we maintain image proportions?
Derek Allard2067d1a2008-11-13 22:59:24 +0000578 *
579 * When creating thumbs or copies, the target width/height
580 * might not be in correct proportion with the source
Andrey Andreev8e70b792012-01-12 20:19:24 +0200581 * image's width/height. We'll recalculate it here.
Derek Allard2067d1a2008-11-13 22:59:24 +0000582 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200583 if ($this->maintain_ratio === TRUE && ($this->width != 0 OR $this->height != 0))
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 {
585 $this->image_reproportion();
586 }
587
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200588 /* Was a width and height specified?
Derek Allard2067d1a2008-11-13 22:59:24 +0000589 *
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200590 * If the destination width/height was not submitted we
591 * will use the values from the actual file
Derek Allard2067d1a2008-11-13 22:59:24 +0000592 */
593 if ($this->width == '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200594 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000595 $this->width = $this->orig_width;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200596 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000597
598 if ($this->height == '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200599 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000600 $this->height = $this->orig_height;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200601 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000602
603 // Set the quality
Andrey Andreev8e70b792012-01-12 20:19:24 +0200604 $this->quality = trim(str_replace('%', '', $this->quality));
Derek Allard2067d1a2008-11-13 22:59:24 +0000605
Andrey Andreev8e70b792012-01-12 20:19:24 +0200606 if ($this->quality == '' OR $this->quality == 0 OR ! preg_match('/^[0-9]+$/', $this->quality))
607 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 $this->quality = 90;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200609 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000610
611 // Set the x/y coordinates
Andrey Andreev8e70b792012-01-12 20:19:24 +0200612 $this->x_axis = ($this->x_axis == '' OR ! preg_match('/^[0-9]+$/', $this->x_axis)) ? 0 : $this->x_axis;
613 $this->y_axis = ($this->y_axis == '' OR ! preg_match('/^[0-9]+$/', $this->y_axis)) ? 0 : $this->y_axis;
Derek Allard2067d1a2008-11-13 22:59:24 +0000614
615 // Watermark-related Stuff...
Derek Allard2067d1a2008-11-13 22:59:24 +0000616 if ($this->wm_overlay_path != '')
617 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200618 $this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
Derek Allard2067d1a2008-11-13 22:59:24 +0000619 }
620
621 if ($this->wm_shadow_color != '')
622 {
623 $this->wm_use_drop_shadow = TRUE;
624 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200625 elseif ($this->wm_use_drop_shadow == TRUE && $this->wm_shadow_color == '')
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200626 {
627 $this->wm_use_drop_shadow = FALSE;
628 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000629
630 if ($this->wm_font_path != '')
631 {
632 $this->wm_use_truetype = TRUE;
633 }
634
635 return TRUE;
636 }
637
638 // --------------------------------------------------------------------
639
640 /**
641 * Image Resize
642 *
643 * This is a wrapper function that chooses the proper
644 * resize function based on the protocol specified
645 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000646 * @return bool
647 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200648 public function resize()
Derek Allard2067d1a2008-11-13 22:59:24 +0000649 {
Andrey Andreev1a9f52c2012-01-07 01:06:34 +0200650 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 return $this->$protocol('resize');
652 }
653
654 // --------------------------------------------------------------------
655
656 /**
657 * Image Crop
658 *
659 * This is a wrapper function that chooses the proper
660 * cropping function based on the protocol specified
661 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000662 * @return bool
663 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200664 public function crop()
Derek Allard2067d1a2008-11-13 22:59:24 +0000665 {
Andrey Andreev5a67e3d2012-01-07 01:21:09 +0200666 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 return $this->$protocol('crop');
668 }
669
670 // --------------------------------------------------------------------
671
672 /**
673 * Image Rotate
674 *
675 * This is a wrapper function that chooses the proper
676 * rotation function based on the protocol specified
677 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000678 * @return bool
679 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200680 public function rotate()
Derek Allard2067d1a2008-11-13 22:59:24 +0000681 {
682 // Allowed rotation values
683 $degs = array(90, 180, 270, 'vrt', 'hor');
684
Derek Allardd9c7f032008-12-01 20:18:00 +0000685 if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs))
Derek Allard2067d1a2008-11-13 22:59:24 +0000686 {
687 $this->set_error('imglib_rotation_angle_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500688 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000689 }
690
691 // Reassign the width and height
692 if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)
693 {
694 $this->width = $this->orig_height;
695 $this->height = $this->orig_width;
696 }
697 else
698 {
699 $this->width = $this->orig_width;
700 $this->height = $this->orig_height;
701 }
702
Derek Allard2067d1a2008-11-13 22:59:24 +0000703 // Choose resizing function
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200704 if ($this->image_library === 'imagemagick' OR $this->image_library === 'netpbm')
Derek Allard2067d1a2008-11-13 22:59:24 +0000705 {
706 $protocol = 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000707 return $this->$protocol('rotate');
708 }
709
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200710 return ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
711 ? $this->image_mirror_gd()
712 : $this->image_rotate_gd();
Derek Allard2067d1a2008-11-13 22:59:24 +0000713 }
714
715 // --------------------------------------------------------------------
716
717 /**
718 * Image Process Using GD/GD2
719 *
720 * This function will resize or crop
721 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000722 * @param string
723 * @return bool
724 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200725 public function image_process_gd($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000726 {
727 $v2_override = FALSE;
728
729 // If the target width/height match the source, AND if the new file name is not equal to the old file name
730 // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
Andrey Andreev8e70b792012-01-12 20:19:24 +0200731 if ($this->dynamic_output === FALSE && $this->orig_width == $this->width && $this->orig_height == $this->height)
Derek Allard2067d1a2008-11-13 22:59:24 +0000732 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200733 if ($this->source_image != $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000734 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200735 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000736 }
Andrey Andreeva92b9032011-12-24 19:05:58 +0200737
738 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000739 }
740
741 // Let's set up our values based on the action
742 if ($action == 'crop')
743 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200744 // Reassign the source width/height if cropping
Derek Jones4b9c6292011-07-01 17:40:48 -0500745 $this->orig_width = $this->width;
Derek Allard2067d1a2008-11-13 22:59:24 +0000746 $this->orig_height = $this->height;
747
748 // GD 2.0 has a cropping bug so we'll test for it
749 if ($this->gd_version() !== FALSE)
750 {
751 $gd_version = str_replace('0', '', $this->gd_version());
752 $v2_override = ($gd_version == 2) ? TRUE : FALSE;
753 }
754 }
755 else
756 {
757 // If resizing the x/y axis must be zero
758 $this->x_axis = 0;
759 $this->y_axis = 0;
760 }
761
Derek Jones4b9c6292011-07-01 17:40:48 -0500762 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000763 if ( ! ($src_img = $this->image_create_gd()))
764 {
765 return FALSE;
766 }
767
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200768 /* Create the image
769 *
770 * Old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
771 * it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
772 * below should that ever prove inaccurate.
773 *
774 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override == FALSE)
775 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200776 if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000777 {
778 $create = 'imagecreatetruecolor';
779 $copy = 'imagecopyresampled';
780 }
781 else
782 {
783 $create = 'imagecreate';
784 $copy = 'imagecopyresized';
785 }
786
787 $dst_img = $create($this->width, $this->height);
Derek Jones595bfd12010-08-20 10:28:22 -0500788
789 if ($this->image_type == 3) // png we can actually preserve transparency
790 {
791 imagealphablending($dst_img, FALSE);
792 imagesavealpha($dst_img, TRUE);
793 }
Barry Mienydd671972010-10-04 16:33:58 +0200794
Derek Allard2067d1a2008-11-13 22:59:24 +0000795 $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
796
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200797 // Show the image
Derek Allard2067d1a2008-11-13 22:59:24 +0000798 if ($this->dynamic_output == TRUE)
799 {
800 $this->image_display_gd($dst_img);
801 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200802 elseif ( ! $this->image_save_gd($dst_img)) // Or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000803 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200804 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000805 }
806
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200807 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000808 imagedestroy($dst_img);
809 imagedestroy($src_img);
810
811 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000812 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000813
814 return TRUE;
815 }
816
817 // --------------------------------------------------------------------
818
819 /**
820 * Image Process Using ImageMagick
821 *
822 * This function will resize, crop or rotate
823 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000824 * @param string
825 * @return bool
826 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200827 public function image_process_imagemagick($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000828 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500829 // Do we have a vaild library path?
Derek Allard2067d1a2008-11-13 22:59:24 +0000830 if ($this->library_path == '')
831 {
832 $this->set_error('imglib_libpath_invalid');
833 return FALSE;
834 }
835
Andrey Andreev8e70b792012-01-12 20:19:24 +0200836 if ( ! preg_match('/convert$/i', $this->library_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000837 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200838 $this->library_path = rtrim($this->library_path, '/').'/convert';
Derek Allard2067d1a2008-11-13 22:59:24 +0000839 }
840
841 // Execute the command
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200842 $cmd = $this->library_path.' -quality '.$this->quality;
Derek Allard2067d1a2008-11-13 22:59:24 +0000843
844 if ($action == 'crop')
845 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200846 $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis.' "'.$this->full_src_path.'" "'.$this->full_dst_path .'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000847 }
848 elseif ($action == 'rotate')
849 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200850 $angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
851 ? '-flop' : '-rotate '.$this->rotation_angle;
Derek Allard2067d1a2008-11-13 22:59:24 +0000852
Andrey Andreev8e70b792012-01-12 20:19:24 +0200853 $cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000854 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200855 else // Resize
Derek Allard2067d1a2008-11-13 22:59:24 +0000856 {
Andrey Andreeve4636302012-01-12 20:23:27 +0200857 $cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000858 }
859
860 $retval = 1;
Derek Allard2067d1a2008-11-13 22:59:24 +0000861 @exec($cmd, $output, $retval);
862
Andrey Andreev8e70b792012-01-12 20:19:24 +0200863 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000864 if ($retval > 0)
865 {
866 $this->set_error('imglib_image_process_failed');
867 return FALSE;
868 }
869
870 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000871 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000872
873 return TRUE;
874 }
875
876 // --------------------------------------------------------------------
877
878 /**
879 * Image Process Using NetPBM
880 *
881 * This function will resize, crop or rotate
882 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000883 * @param string
884 * @return bool
885 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200886 public function image_process_netpbm($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000887 {
888 if ($this->library_path == '')
889 {
890 $this->set_error('imglib_libpath_invalid');
891 return FALSE;
892 }
893
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200894 // Build the resizing command
Derek Allard2067d1a2008-11-13 22:59:24 +0000895 switch ($this->image_type)
896 {
897 case 1 :
898 $cmd_in = 'giftopnm';
899 $cmd_out = 'ppmtogif';
900 break;
901 case 2 :
902 $cmd_in = 'jpegtopnm';
903 $cmd_out = 'ppmtojpeg';
904 break;
905 case 3 :
906 $cmd_in = 'pngtopnm';
907 $cmd_out = 'ppmtopng';
908 break;
909 }
910
911 if ($action == 'crop')
912 {
913 $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
914 }
915 elseif ($action == 'rotate')
916 {
917 switch ($this->rotation_angle)
918 {
919 case 90 : $angle = 'r270';
920 break;
921 case 180 : $angle = 'r180';
922 break;
Barry Mienydd671972010-10-04 16:33:58 +0200923 case 270 : $angle = 'r90';
Derek Allard2067d1a2008-11-13 22:59:24 +0000924 break;
925 case 'vrt' : $angle = 'tb';
926 break;
927 case 'hor' : $angle = 'lr';
928 break;
929 }
930
931 $cmd_inner = 'pnmflip -'.$angle.' ';
932 }
933 else // Resize
934 {
935 $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
936 }
937
938 $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
939
940 $retval = 1;
Derek Allard2067d1a2008-11-13 22:59:24 +0000941 @exec($cmd, $output, $retval);
942
Andrey Andreev8e70b792012-01-12 20:19:24 +0200943 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000944 if ($retval > 0)
945 {
946 $this->set_error('imglib_image_process_failed');
947 return FALSE;
948 }
949
950 // With NetPBM we have to create a temporary image.
951 // If you try manipulating the original it fails so
952 // we have to rename the temp file.
953 copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200954 unlink($this->dest_folder.'netpbm.tmp');
Derek Jones172e1612009-10-13 14:32:48 +0000955 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000956
957 return TRUE;
958 }
959
960 // --------------------------------------------------------------------
961
962 /**
963 * Image Rotate Using GD
964 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000965 * @return bool
966 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200967 public function image_rotate_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +0000968 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200969 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000970 if ( ! ($src_img = $this->image_create_gd()))
971 {
972 return FALSE;
973 }
974
975 // Set the background color
976 // This won't work with transparent PNG files so we are
977 // going to have to figure out how to determine the color
978 // of the alpha channel in a future release.
979
980 $white = imagecolorallocate($src_img, 255, 255, 255);
981
Andrey Andreev8e70b792012-01-12 20:19:24 +0200982 // Rotate it!
Derek Allard2067d1a2008-11-13 22:59:24 +0000983 $dst_img = imagerotate($src_img, $this->rotation_angle, $white);
984
Andrey Andreev8e70b792012-01-12 20:19:24 +0200985 // Show the image
Derek Allard2067d1a2008-11-13 22:59:24 +0000986 if ($this->dynamic_output == TRUE)
987 {
988 $this->image_display_gd($dst_img);
989 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200990 elseif ( ! $this->image_save_gd($dst_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000991 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200992 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000993 }
994
Andrey Andreev8e70b792012-01-12 20:19:24 +0200995 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000996 imagedestroy($dst_img);
997 imagedestroy($src_img);
998
999 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +00001000 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001001
Pascal Kriete8761ef52011-02-14 13:13:52 -05001002 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001003 }
1004
1005 // --------------------------------------------------------------------
1006
1007 /**
1008 * Create Mirror Image using GD
1009 *
1010 * This function will flip horizontal or vertical
1011 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001012 * @return bool
1013 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001014 public function image_mirror_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +00001015 {
1016 if ( ! $src_img = $this->image_create_gd())
1017 {
1018 return FALSE;
1019 }
1020
Derek Jones4b9c6292011-07-01 17:40:48 -05001021 $width = $this->orig_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001022 $height = $this->orig_height;
1023
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001024 if ($this->rotation_angle === 'hor')
Derek Allard2067d1a2008-11-13 22:59:24 +00001025 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001026 for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001027 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001028 while ($left < $right)
1029 {
1030 $cl = imagecolorat($src_img, $left, $i);
1031 $cr = imagecolorat($src_img, $right, $i);
1032
1033 imagesetpixel($src_img, $left, $i, $cr);
1034 imagesetpixel($src_img, $right, $i, $cl);
1035
1036 $left++;
1037 $right--;
1038 }
1039 }
1040 }
1041 else
1042 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001043 for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001044 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001045 while ($top < $bot)
1046 {
1047 $ct = imagecolorat($src_img, $i, $top);
1048 $cb = imagecolorat($src_img, $i, $bot);
1049
1050 imagesetpixel($src_img, $i, $top, $cb);
1051 imagesetpixel($src_img, $i, $bot, $ct);
1052
1053 $top++;
1054 $bot--;
1055 }
1056 }
1057 }
1058
Andrey Andreev8e70b792012-01-12 20:19:24 +02001059 // Show the image
Derek Allard2067d1a2008-11-13 22:59:24 +00001060 if ($this->dynamic_output == TRUE)
1061 {
1062 $this->image_display_gd($src_img);
1063 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001064 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001065 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001066 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001067 }
1068
Andrey Andreev8e70b792012-01-12 20:19:24 +02001069 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001070 imagedestroy($src_img);
1071
1072 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +00001073 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001074
1075 return TRUE;
1076 }
1077
1078 // --------------------------------------------------------------------
1079
1080 /**
1081 * Image Watermark
1082 *
1083 * This is a wrapper function that chooses the type
1084 * of watermarking based on the specified preference.
1085 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001086 * @return bool
1087 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001088 public function watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001089 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001090 return ($this->wm_type === 'overlay') ? $this->overlay_watermark() : $this->text_watermark();
Derek Allard2067d1a2008-11-13 22:59:24 +00001091 }
1092
1093 // --------------------------------------------------------------------
1094
1095 /**
1096 * Watermark - Graphic Version
1097 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001098 * @return bool
1099 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001100 public function overlay_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001101 {
1102 if ( ! function_exists('imagecolortransparent'))
1103 {
1104 $this->set_error('imglib_gd_required');
1105 return FALSE;
1106 }
1107
Andrey Andreev8e70b792012-01-12 20:19:24 +02001108 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001109 $this->get_image_properties();
1110
Andrey Andreev8e70b792012-01-12 20:19:24 +02001111 // Fetch watermark image properties
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001112 $props = $this->get_image_properties($this->wm_overlay_path, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001113 $wm_img_type = $props['image_type'];
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001114 $wm_width = $props['width'];
1115 $wm_height = $props['height'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001116
Andrey Andreev8e70b792012-01-12 20:19:24 +02001117 // Create two image resources
Derek Jones4b9c6292011-07-01 17:40:48 -05001118 $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001119 $src_img = $this->image_create_gd($this->full_src_path);
1120
1121 // Reverse the offset if necessary
1122 // When the image is positioned at the bottom
1123 // we don't want the vertical offset to push it
Andrey Andreev8e70b792012-01-12 20:19:24 +02001124 // further down. We want the reverse, so we'll
1125 // invert the offset. Same with the horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001126 // offset when the image is at the right
1127
Andrey Andreev8e70b792012-01-12 20:19:24 +02001128 $this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
1129 $this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001130
1131 if ($this->wm_vrt_alignment == 'B')
1132 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1133
1134 if ($this->wm_hor_alignment == 'R')
1135 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1136
Andrey Andreev8e70b792012-01-12 20:19:24 +02001137 // Set the base x and y axis values
Derek Allard2067d1a2008-11-13 22:59:24 +00001138 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1139 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1140
Andrey Andreev8e70b792012-01-12 20:19:24 +02001141 // Set the vertical position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001142 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001143 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001144 $y_axis += ($this->orig_height / 2) - ($wm_height / 2);
1145 }
1146 elseif ($this->wm_vrt_alignment === 'B')
1147 {
1148 $y_axis += $this->orig_height - $wm_height;
Derek Allard2067d1a2008-11-13 22:59:24 +00001149 }
1150
Andrey Andreev8e70b792012-01-12 20:19:24 +02001151 // Set the horizontal position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001152 if ($this->wm_hor_alignment === 'C')
Derek Allard2067d1a2008-11-13 22:59:24 +00001153 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001154 $x_axis += ($this->orig_width / 2) - ($wm_width / 2);
1155 }
1156 elseif ($this->wm_hor_alignment === 'R')
1157 {
1158 $x_axis += $this->orig_width - $wm_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001159 }
1160
Derek Jones4b9c6292011-07-01 17:40:48 -05001161 // Build the finalized image
Andrey Andreev8e70b792012-01-12 20:19:24 +02001162 if ($wm_img_type == 3 && function_exists('imagealphablending'))
Derek Allard2067d1a2008-11-13 22:59:24 +00001163 {
1164 @imagealphablending($src_img, TRUE);
Barry Mienydd671972010-10-04 16:33:58 +02001165 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001166
1167 // Set RGB values for text and shadow
1168 $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
1169 $alpha = ($rgba & 0x7F000000) >> 24;
1170
1171 // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1172 if ($alpha > 0)
1173 {
1174 // copy the image directly, the image's alpha transparency being the sole determinant of blending
1175 imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
1176 }
1177 else
1178 {
1179 // set our RGB value from above to be transparent and merge the images with the specified opacity
1180 imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
1181 imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
1182 }
1183
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001184 // Output the image
Derek Allard2067d1a2008-11-13 22:59:24 +00001185 if ($this->dynamic_output == TRUE)
1186 {
1187 $this->image_display_gd($src_img);
1188 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001189 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001190 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001191 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001192 }
1193
1194 imagedestroy($src_img);
1195 imagedestroy($wm_img);
1196
1197 return TRUE;
1198 }
1199
1200 // --------------------------------------------------------------------
1201
1202 /**
1203 * Watermark - Text Version
1204 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001205 * @return bool
1206 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001207 public function text_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001208 {
1209 if ( ! ($src_img = $this->image_create_gd()))
1210 {
1211 return FALSE;
1212 }
1213
Andrey Andreev8e70b792012-01-12 20:19:24 +02001214 if ($this->wm_use_truetype == TRUE && ! file_exists($this->wm_font_path))
Derek Allard2067d1a2008-11-13 22:59:24 +00001215 {
1216 $this->set_error('imglib_missing_font');
1217 return FALSE;
1218 }
1219
Andrey Andreev8e70b792012-01-12 20:19:24 +02001220 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001221 $this->get_image_properties();
1222
Derek Allard2067d1a2008-11-13 22:59:24 +00001223 // Reverse the vertical offset
1224 // When the image is positioned at the bottom
1225 // we don't want the vertical offset to push it
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001226 // further down. We want the reverse, so we'll
Andrey Andreev8e70b792012-01-12 20:19:24 +02001227 // invert the offset. Note: The horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001228 // offset flips itself automatically
1229
1230 if ($this->wm_vrt_alignment == 'B')
1231 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1232
1233 if ($this->wm_hor_alignment == 'R')
1234 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1235
1236 // Set font width and height
1237 // These are calculated differently depending on
1238 // whether we are using the true type font or not
1239 if ($this->wm_use_truetype == TRUE)
1240 {
1241 if ($this->wm_font_size == '')
Andrey Andreeva92b9032011-12-24 19:05:58 +02001242 {
1243 $this->wm_font_size = 17;
1244 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001245
Derek Jones4b9c6292011-07-01 17:40:48 -05001246 $fontwidth = $this->wm_font_size-($this->wm_font_size/4);
Derek Allard2067d1a2008-11-13 22:59:24 +00001247 $fontheight = $this->wm_font_size;
1248 $this->wm_vrt_offset += $this->wm_font_size;
1249 }
1250 else
1251 {
Derek Jones4b9c6292011-07-01 17:40:48 -05001252 $fontwidth = imagefontwidth($this->wm_font_size);
Derek Allard2067d1a2008-11-13 22:59:24 +00001253 $fontheight = imagefontheight($this->wm_font_size);
1254 }
1255
1256 // Set base X and Y axis values
1257 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1258 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1259
Derek Allard2067d1a2008-11-13 22:59:24 +00001260 if ($this->wm_use_drop_shadow == FALSE)
1261 $this->wm_shadow_distance = 0;
1262
1263 $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
1264 $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
1265
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001266 // Set verticle alignment
1267 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001268 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001269 $y_axis += ($this->orig_height / 2) + ($fontheight / 2);
1270 }
1271 elseif ($this->wm_vrt_alignment === 'B')
1272 {
1273 $y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2);
Derek Allard2067d1a2008-11-13 22:59:24 +00001274 }
1275
1276 $x_shad = $x_axis + $this->wm_shadow_distance;
1277 $y_shad = $y_axis + $this->wm_shadow_distance;
1278
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001279 if ($this->wm_use_drop_shadow)
Derek Allard2067d1a2008-11-13 22:59:24 +00001280 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001281 // Set horizontal alignment
1282 if ($this->wm_hor_alignment === 'R')
1283 {
1284 $x_shad += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1285 $x_axis += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1286 }
1287 elseif ($this->wm_hor_alignment === 'C')
1288 {
1289 $x_shad += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1290 $x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1291 }
1292
Andrey Andreev8323ae62011-12-31 18:39:10 +02001293 /* Set RGB values for text and shadow
1294 *
1295 * First character is #, so we don't really need it.
1296 * Get the rest of the string and split it into 2-length
1297 * hex values:
1298 */
1299 $txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001300 $txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
Andrey Andreev8323ae62011-12-31 18:39:10 +02001301 $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
Ronald Beilsma8f80bc42012-01-12 16:41:49 +01001302 $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001303
Andrey Andreev8e70b792012-01-12 20:19:24 +02001304 // Add the text to the source image
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001305 if ($this->wm_use_truetype)
1306 {
1307 imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
1308 imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
1309 }
1310 else
1311 {
1312 imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
1313 imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
1314 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001315 }
1316
Andrey Andreev8e70b792012-01-12 20:19:24 +02001317 // Output the final image
Derek Allard2067d1a2008-11-13 22:59:24 +00001318 if ($this->dynamic_output == TRUE)
1319 {
1320 $this->image_display_gd($src_img);
1321 }
1322 else
1323 {
1324 $this->image_save_gd($src_img);
1325 }
1326
1327 imagedestroy($src_img);
1328
1329 return TRUE;
1330 }
1331
1332 // --------------------------------------------------------------------
1333
1334 /**
1335 * Create Image - GD
1336 *
1337 * This simply creates an image resource handle
1338 * based on the type of image being processed
1339 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001340 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001341 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001342 * @return resource
1343 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001344 public function image_create_gd($path = '', $image_type = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001345 {
1346 if ($path == '')
1347 $path = $this->full_src_path;
1348
1349 if ($image_type == '')
1350 $image_type = $this->image_type;
1351
1352
1353 switch ($image_type)
1354 {
1355 case 1 :
1356 if ( ! function_exists('imagecreatefromgif'))
1357 {
1358 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1359 return FALSE;
1360 }
1361
1362 return imagecreatefromgif($path);
1363 break;
1364 case 2 :
1365 if ( ! function_exists('imagecreatefromjpeg'))
1366 {
1367 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1368 return FALSE;
1369 }
1370
1371 return imagecreatefromjpeg($path);
1372 break;
1373 case 3 :
1374 if ( ! function_exists('imagecreatefrompng'))
1375 {
1376 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1377 return FALSE;
1378 }
1379
1380 return imagecreatefrompng($path);
1381 break;
1382
1383 }
1384
1385 $this->set_error(array('imglib_unsupported_imagecreate'));
1386 return FALSE;
1387 }
1388
1389 // --------------------------------------------------------------------
1390
1391 /**
1392 * Write image file to disk - GD
1393 *
1394 * Takes an image resource as input and writes the file
1395 * to the specified destination
1396 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001397 * @param resource
1398 * @return bool
1399 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001400 public function image_save_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001401 {
1402 switch ($this->image_type)
1403 {
1404 case 1 :
1405 if ( ! function_exists('imagegif'))
1406 {
1407 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1408 return FALSE;
1409 }
1410
Derek Jones541ddbd2008-12-09 15:25:31 +00001411 if ( ! @imagegif($resource, $this->full_dst_path))
1412 {
1413 $this->set_error('imglib_save_failed');
1414 return FALSE;
1415 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001416 break;
1417 case 2 :
1418 if ( ! function_exists('imagejpeg'))
1419 {
1420 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1421 return FALSE;
1422 }
1423
Derek Jones541ddbd2008-12-09 15:25:31 +00001424 if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
1425 {
1426 $this->set_error('imglib_save_failed');
1427 return FALSE;
1428 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001429 break;
1430 case 3 :
1431 if ( ! function_exists('imagepng'))
1432 {
1433 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1434 return FALSE;
1435 }
1436
Derek Jones541ddbd2008-12-09 15:25:31 +00001437 if ( ! @imagepng($resource, $this->full_dst_path))
1438 {
1439 $this->set_error('imglib_save_failed');
1440 return FALSE;
1441 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001442 break;
1443 default :
1444 $this->set_error(array('imglib_unsupported_imagecreate'));
1445 return FALSE;
1446 break;
1447 }
1448
1449 return TRUE;
1450 }
1451
1452 // --------------------------------------------------------------------
1453
1454 /**
1455 * Dynamically outputs an image
1456 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001457 * @param resource
1458 * @return void
1459 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001460 public function image_display_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001461 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001462 header('Content-Disposition: filename='.$this->source_image.';');
1463 header('Content-Type: '.$this->mime_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001464 header('Content-Transfer-Encoding: binary');
1465 header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
1466
1467 switch ($this->image_type)
1468 {
Barry Mienydd671972010-10-04 16:33:58 +02001469 case 1 : imagegif($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001470 break;
1471 case 2 : imagejpeg($resource, '', $this->quality);
1472 break;
1473 case 3 : imagepng($resource);
1474 break;
1475 default : echo 'Unable to display the image';
1476 break;
1477 }
1478 }
1479
1480 // --------------------------------------------------------------------
1481
1482 /**
1483 * Re-proportion Image Width/Height
1484 *
1485 * When creating thumbs, the desired width/height
1486 * can end up warping the image due to an incorrect
1487 * ratio between the full-sized image and the thumb.
1488 *
1489 * This function lets us re-proportion the width/height
1490 * if users choose to maintain the aspect ratio when resizing.
1491 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001492 * @return void
1493 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001494 public function image_reproportion()
Derek Allard2067d1a2008-11-13 22:59:24 +00001495 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001496 if (($this->width == 0 && $this->height == 0) OR $this->orig_width == 0 OR $this->orig_height == 0
1497 OR ( ! preg_match('/^[0-9]+$/', $this->width) && ! preg_match('/^[0-9]+$/', $this->height))
1498 OR ! preg_match('/^[0-9]+$/', $this->orig_width) OR ! preg_match('/^[0-9]+$/', $this->orig_height))
Derek Allard2067d1a2008-11-13 22:59:24 +00001499 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001500 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001501 }
1502
Andrey Andreev8e70b792012-01-12 20:19:24 +02001503 // Sanitize so we don't call preg_match() anymore
1504 $this->width = (int) $this->width;
1505 $this->height = (int) $this->height;
1506
1507 if ($this->master_dim !== 'width' && $this->master_dim !== 'height')
Derek Allard2067d1a2008-11-13 22:59:24 +00001508 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001509 if ($this->width > 0 && $this->height > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001510 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001511 $this->master_dim = ((($this->orig_height/$this->orig_width) - ($this->height/$this->width)) < 0)
1512 ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001513 }
1514 else
1515 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001516 $this->master_dim = ($this->height === 0) ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001517 }
1518 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001519 elseif (($this->master_dim === 'width' && $this->width === 0)
1520 OR ($this->master_dim === 'height' && $this->height === 0))
1521 {
1522 return;
1523 }
1524
1525 if ($this->master_dim === 'width')
1526 {
1527 $this->height = (int) ceil($this->width*$this->orig_height/$this->orig_width);
1528 }
1529 else
1530 {
1531 $this->width = (int) ceil($this->orig_width*$this->height/$this->orig_height);
1532 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001533 }
1534
1535 // --------------------------------------------------------------------
1536
1537 /**
1538 * Get image properties
1539 *
1540 * A helper function that gets info about the file
1541 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001542 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001543 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001544 * @return mixed
1545 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001546 public function get_image_properties($path = '', $return = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001547 {
1548 // For now we require GD but we should
1549 // find a way to determine this using IM or NetPBM
1550
1551 if ($path == '')
Andrey Andreev8e70b792012-01-12 20:19:24 +02001552 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001553 $path = $this->full_src_path;
Andrey Andreev8e70b792012-01-12 20:19:24 +02001554 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001555
1556 if ( ! file_exists($path))
1557 {
1558 $this->set_error('imglib_invalid_path');
1559 return FALSE;
1560 }
1561
Phil Sturgeon901998a2011-08-26 10:03:33 +01001562 $vals = getimagesize($path);
Derek Allard2067d1a2008-11-13 22:59:24 +00001563 $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
Andrey Andreeva92b9032011-12-24 19:05:58 +02001564 $mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001565
1566 if ($return == TRUE)
1567 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001568 return array(
1569 'width' => $vals[0],
1570 'height' => $vals[1],
1571 'image_type' => $vals[2],
1572 'size_str' => $vals[3],
1573 'mime_type' => $mime
1574 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001575 }
1576
Andrey Andreeva92b9032011-12-24 19:05:58 +02001577 $this->orig_width = $vals[0];
1578 $this->orig_height = $vals[1];
1579 $this->image_type = $vals[2];
1580 $this->size_str = $vals[3];
Derek Allard2067d1a2008-11-13 22:59:24 +00001581 $this->mime_type = $mime;
1582
1583 return TRUE;
1584 }
1585
1586 // --------------------------------------------------------------------
1587
1588 /**
1589 * Size calculator
1590 *
1591 * This function takes a known width x height and
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001592 * recalculates it to a new size. Only one
Derek Allard2067d1a2008-11-13 22:59:24 +00001593 * new variable needs to be known
1594 *
1595 * $props = array(
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001596 * 'width' => $width,
1597 * 'height' => $height,
1598 * 'new_width' => 40,
1599 * 'new_height' => ''
1600 * );
Derek Allard2067d1a2008-11-13 22:59:24 +00001601 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001602 * @param array
1603 * @return array
1604 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001605 public function size_calculator($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001606 {
1607 if ( ! is_array($vals))
1608 {
1609 return;
1610 }
1611
1612 $allowed = array('new_width', 'new_height', 'width', 'height');
1613
1614 foreach ($allowed as $item)
1615 {
1616 if ( ! isset($vals[$item]) OR $vals[$item] == '')
1617 $vals[$item] = 0;
1618 }
1619
1620 if ($vals['width'] == 0 OR $vals['height'] == 0)
1621 {
1622 return $vals;
1623 }
1624
1625 if ($vals['new_width'] == 0)
1626 {
1627 $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1628 }
1629 elseif ($vals['new_height'] == 0)
1630 {
1631 $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1632 }
1633
1634 return $vals;
1635 }
1636
1637 // --------------------------------------------------------------------
1638
1639 /**
1640 * Explode source_image
1641 *
1642 * This is a helper function that extracts the extension
Derek Jones4b9c6292011-07-01 17:40:48 -05001643 * from the source_image. This function lets us deal with
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001644 * source_images with multiple periods, like: my.cool.jpg
Derek Allard2067d1a2008-11-13 22:59:24 +00001645 * It returns an associative array with two elements:
Derek Jones4b9c6292011-07-01 17:40:48 -05001646 * $array['ext'] = '.jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001647 * $array['name'] = 'my.cool';
1648 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001649 * @param array
1650 * @return array
1651 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001652 public function explode_name($source_image)
Derek Allard2067d1a2008-11-13 22:59:24 +00001653 {
Derek Jones08cae632009-02-10 20:03:29 +00001654 $ext = strrchr($source_image, '.');
1655 $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
Barry Mienydd671972010-10-04 16:33:58 +02001656
Derek Jones08cae632009-02-10 20:03:29 +00001657 return array('ext' => $ext, 'name' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001658 }
1659
1660 // --------------------------------------------------------------------
1661
1662 /**
1663 * Is GD Installed?
1664 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001665 * @return bool
1666 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001667 public function gd_loaded()
Derek Allard2067d1a2008-11-13 22:59:24 +00001668 {
1669 if ( ! extension_loaded('gd'))
1670 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001671 /* As it is stated in the PHP manual, dl() is not always available
1672 * and even if so - it could generate an E_WARNING message on failure
1673 */
Andrey Andreev8e70b792012-01-12 20:19:24 +02001674 return (function_exists('dl') && @dl('gd.so'));
Derek Allard2067d1a2008-11-13 22:59:24 +00001675 }
1676
1677 return TRUE;
1678 }
1679
1680 // --------------------------------------------------------------------
1681
1682 /**
1683 * Get GD version
1684 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001685 * @return mixed
1686 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001687 public function gd_version()
Derek Allard2067d1a2008-11-13 22:59:24 +00001688 {
1689 if (function_exists('gd_info'))
1690 {
1691 $gd_version = @gd_info();
Andrey Andreev8e70b792012-01-12 20:19:24 +02001692 return preg_replace('/\D/', '', $gd_version['GD Version']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001693 }
1694
1695 return FALSE;
1696 }
1697
1698 // --------------------------------------------------------------------
1699
1700 /**
1701 * Set error message
1702 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001703 * @param string
1704 * @return void
1705 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001706 public function set_error($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +00001707 {
1708 $CI =& get_instance();
1709 $CI->lang->load('imglib');
1710
1711 if (is_array($msg))
1712 {
1713 foreach ($msg as $val)
1714 {
1715
1716 $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
1717 $this->error_msg[] = $msg;
1718 log_message('error', $msg);
1719 }
1720 }
1721 else
1722 {
1723 $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
1724 $this->error_msg[] = $msg;
1725 log_message('error', $msg);
1726 }
1727 }
1728
1729 // --------------------------------------------------------------------
1730
1731 /**
1732 * Show error messages
1733 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001734 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001735 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001736 * @return string
1737 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001738 public function display_errors($open = '<p>', $close = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +00001739 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001740 return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001741 }
1742
1743}
Derek Allard2067d1a2008-11-13 22:59:24 +00001744
1745/* End of file Image_lib.php */
Andrey Andreev1b815532012-04-03 16:06:03 +03001746/* Location: ./system/libraries/Image_lib.php */