blob: ef41878472801ade3bfe0bb5ef6f8f3947ae37aa [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
Andrey Andreev56454792012-05-17 14:32:19 +030041 * Can be: imagemagick, netpbm, gd, gd2
Timothy Warrenb8e62852012-04-26 18:40:54 -040042 *
43 * @var string
44 */
45 public $image_library = 'gd2';
Andrey Andreev56454792012-05-17 14:32:19 +030046
Timothy Warrenb8e62852012-04-26 18:40:54 -040047 /**
48 * Path to the graphic library (if applicable)
49 *
50 * @var string
51 */
Andrey Andreev3a459572011-12-21 11:23:11 +020052 public $library_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +030053
Timothy Warrenb8e62852012-04-26 18:40:54 -040054 /**
55 * Whether to send to browser or write to disk
56 *
57 * @var bool
58 */
59 public $dynamic_output = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +030060
Timothy Warrenb8e62852012-04-26 18:40:54 -040061 /**
62 * Path to original image
63 *
64 * @var string
65 */
Andrey Andreev3a459572011-12-21 11:23:11 +020066 public $source_image = '';
Andrey Andreev56454792012-05-17 14:32:19 +030067
Timothy Warrenb8e62852012-04-26 18:40:54 -040068 /**
69 * Path to the modified image
70 *
71 * @var string
72 */
Andrey Andreev56454792012-05-17 14:32:19 +030073 public $new_image = '';
74
Timothy Warrenb8e62852012-04-26 18:40:54 -040075 /**
76 * Image width
77 *
78 * @var int
79 */
Andrey Andreev56454792012-05-17 14:32:19 +030080 public $width = '';
81
Timothy Warrenb8e62852012-04-26 18:40:54 -040082 /**
83 * Image height
84 *
85 * @var int
86 */
Andrey Andreev56454792012-05-17 14:32:19 +030087 public $height = '';
88
Timothy Warrenb8e62852012-04-26 18:40:54 -040089 /**
90 * Quality percentage of new image
91 *
92 * @var int
93 */
Andrey Andreev56454792012-05-17 14:32:19 +030094 public $quality = 90;
95
Timothy Warrenb8e62852012-04-26 18:40:54 -040096 /**
97 * Whether to create a thumbnail
98 *
99 * @var bool
100 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200101 public $create_thumb = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300102
Timothy Warrenb8e62852012-04-26 18:40:54 -0400103 /**
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';
Andrey Andreev56454792012-05-17 14:32:19 +0300109
Timothy Warrenb8e62852012-04-26 18:40:54 -0400110 /**
111 * Whether to maintain aspect ratio when resizing or use hard values
112 *
113 * @var bool
114 */
115 public $maintain_ratio = TRUE;
Andrey Andreev56454792012-05-17 14:32:19 +0300116
Timothy Warrenb8e62852012-04-26 18:40:54 -0400117 /**
118 * auto, height, or width. Determines what to use as the master dimension
119 *
120 * @var string
121 */
Andrey Andreev56454792012-05-17 14:32:19 +0300122 public $master_dim = 'auto';
123
Timothy Warrenb8e62852012-04-26 18:40:54 -0400124 /**
125 * Angle at to rotate image
126 *
127 * @var string
128 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200129 public $rotation_angle = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300130
Timothy Warrenb8e62852012-04-26 18:40:54 -0400131 /**
132 * X Coordinate for manipulation of the current image
133 *
134 * @var int
135 */
Andrey Andreev56454792012-05-17 14:32:19 +0300136 public $x_axis = '';
137
Timothy Warrenb8e62852012-04-26 18:40:54 -0400138 /**
139 * Y Coordinate for manipulation of the current image
140 *
141 * @var int
142 */
Andrey Andreev56454792012-05-17 14:32:19 +0300143 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 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +0300148
Timothy Warrenb8e62852012-04-26 18:40:54 -0400149 /**
150 * Watermark text if graphic is not used
151 *
152 * @var string
153 */
154 public $wm_text = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300155
Timothy Warrenb8e62852012-04-26 18:40:54 -0400156 /**
157 * Type of watermarking. Options: text/overlay
158 *
159 * @var string
160 */
161 public $wm_type = 'text';
Andrey Andreev56454792012-05-17 14:32:19 +0300162
Timothy Warrenb8e62852012-04-26 18:40:54 -0400163 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400164 * Default transparency for watermark
Andrey Andreev56454792012-05-17 14:32:19 +0300165 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400166 * @var int
167 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200168 public $wm_x_transp = 4;
Andrey Andreev56454792012-05-17 14:32:19 +0300169
Timothy Warrenb8e62852012-04-26 18:40:54 -0400170 /**
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;
Andrey Andreev56454792012-05-17 14:32:19 +0300176
Timothy Warrenb8e62852012-04-26 18:40:54 -0400177 /**
178 * Watermark image path
Andrey Andreev56454792012-05-17 14:32:19 +0300179 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400180 * @var string
181 */
Andrey Andreev56454792012-05-17 14:32:19 +0300182 public $wm_overlay_path = '';
183
Timothy Warrenb8e62852012-04-26 18:40:54 -0400184 /**
185 * TT font
186 *
187 * @var string
188 */
189 public $wm_font_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300190
Timothy Warrenb8e62852012-04-26 18:40:54 -0400191 /**
192 * Font size (different versions of GD will either use points or pixels)
193 *
194 * @var int
195 */
196 public $wm_font_size = 17;
Andrey Andreev56454792012-05-17 14:32:19 +0300197
Timothy Warrenb8e62852012-04-26 18:40:54 -0400198 /**
199 * Vertical alignment: T M B
200 *
201 * @var string
202 */
203 public $wm_vrt_alignment = 'B';
Andrey Andreev56454792012-05-17 14:32:19 +0300204
Timothy Warrenb8e62852012-04-26 18:40:54 -0400205 /**
206 * Horizontal alignment: L R C
207 *
208 * @var string
209 */
210 public $wm_hor_alignment = 'C';
Andrey Andreev56454792012-05-17 14:32:19 +0300211
Timothy Warrenb8e62852012-04-26 18:40:54 -0400212 /**
213 * Padding around text
214 *
215 * @var int
216 */
217 public $wm_padding = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300218
Timothy Warrenb8e62852012-04-26 18:40:54 -0400219 /**
220 * Lets you push text to the right
221 *
222 * @var int
223 */
224 public $wm_hor_offset = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300225
Timothy Warrenb8e62852012-04-26 18:40:54 -0400226 /**
227 * Lets you push text down
228 *
229 * @var int
230 */
231 public $wm_vrt_offset = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300232
Timothy Warrenb8e62852012-04-26 18:40:54 -0400233 /**
234 * Text color
235 *
236 * @var string
237 */
Andrey Andreev56454792012-05-17 14:32:19 +0300238 protected $wm_font_color = '#ffffff';
239
Timothy Warrenb8e62852012-04-26 18:40:54 -0400240 /**
241 * Dropshadow color
242 *
243 * @var string
244 */
Andrey Andreev56454792012-05-17 14:32:19 +0300245 protected $wm_shadow_color = '';
246
Timothy Warrenb8e62852012-04-26 18:40:54 -0400247 /**
248 * Dropshadow distance
249 *
250 * @var int
251 */
252 public $wm_shadow_distance = 2;
Andrey Andreev56454792012-05-17 14:32:19 +0300253
Timothy Warrenb8e62852012-04-26 18:40:54 -0400254 /**
255 * Image opacity: 1 - 100 Only works with image
256 *
257 * @var int
258 */
Andrey Andreev56454792012-05-17 14:32:19 +0300259 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 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +0300264
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 = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300271
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400272 /**
273 * Destination image folder
274 *
275 * @var string
276 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200277 public $dest_folder = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300278
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400279 /**
280 * Image mime-type
281 *
282 * @var string
283 */
Andrey Andreev56454792012-05-17 14:32:19 +0300284 public $mime_type = '';
285
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400286 /**
Andrey Andreev56454792012-05-17 14:32:19 +0300287 * Original image width
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400288 *
289 * @var int
290 */
Andrey Andreev56454792012-05-17 14:32:19 +0300291 public $orig_width = '';
292
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400293 /**
294 * Original image height
295 *
296 * @var int
297 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200298 public $orig_height = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300299
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400300 /**
301 * Image format
Andrey Andreev56454792012-05-17 14:32:19 +0300302 *
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400303 * @var string
304 */
Andrey Andreev56454792012-05-17 14:32:19 +0300305 public $image_type = '';
306
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400307 /**
308 * Size of current image
309 *
310 * @var string
311 */
Andrey Andreev56454792012-05-17 14:32:19 +0300312 public $size_str = '';
313
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400314 /**
315 * Full path to source image
316 *
317 * @var string
318 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200319 public $full_src_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300320
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400321 /**
322 * Full path to destination image
323 *
324 * @var string
325 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200326 public $full_dst_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300327
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400328 /**
329 * Name of function to create image
330 *
331 * @var string
332 */
Andrey Andreev56454792012-05-17 14:32:19 +0300333 public $create_fnc = 'imagecreatetruecolor';
334
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400335 /**
336 * Name of function to copy image
337 *
338 * @var string
339 */
Andrey Andreev56454792012-05-17 14:32:19 +0300340 public $copy_fnc = 'imagecopyresampled';
341
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400342 /**
343 * Error messages
344 *
345 * @var array
346 */
Andrey Andreev56454792012-05-17 14:32:19 +0300347 public $error_msg = array();
348
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400349 /**
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;
Andrey Andreev56454792012-05-17 14:32:19 +0300355
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400356 /**
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
Andrey Andreev56454792012-05-17 14:32:19 +0300367 * @return void
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400368 */
Greg Akera9263282010-11-10 15:26:43 -0600369 public function __construct($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 {
371 if (count($props) > 0)
372 {
373 $this->initialize($props);
374 }
375
Andrey Andreev8e70b792012-01-12 20:19:24 +0200376 log_message('debug', 'Image Lib Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000377 }
378
379 // --------------------------------------------------------------------
380
381 /**
382 * Initialize image properties
383 *
384 * Resets values in case this class is used in a loop
385 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 * @return void
387 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200388 public function clear()
Derek Allard2067d1a2008-11-13 22:59:24 +0000389 {
Michael Denniscb07a322011-08-20 23:40:59 -0700390 $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 +0000391
392 foreach ($props as $val)
393 {
394 $this->$val = '';
395 }
396
Michael Denniscb07a322011-08-20 23:40:59 -0700397 $this->image_library = 'gd2';
398 $this->dynamic_output = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300399 $this->quality = 90;
Michael Denniscb07a322011-08-20 23:40:59 -0700400 $this->create_thumb = FALSE;
401 $this->thumb_marker = '_thumb';
402 $this->maintain_ratio = TRUE;
403 $this->master_dim = 'auto';
404 $this->wm_type = 'text';
405 $this->wm_x_transp = 4;
406 $this->wm_y_transp = 4;
407 $this->wm_font_size = 17;
408 $this->wm_vrt_alignment = 'B';
409 $this->wm_hor_alignment = 'C';
410 $this->wm_padding = 0;
411 $this->wm_hor_offset = 0;
412 $this->wm_vrt_offset = 0;
413 $this->wm_font_color = '#ffffff';
414 $this->wm_shadow_distance = 2;
415 $this->wm_opacity = 50;
416 $this->create_fnc = 'imagecreatetruecolor';
417 $this->copy_fnc = 'imagecopyresampled';
418 $this->error_msg = array();
419 $this->wm_use_drop_shadow = FALSE;
420 $this->wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000421 }
422
423 // --------------------------------------------------------------------
424
425 /**
426 * initialize image preferences
427 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000428 * @param array
429 * @return bool
430 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200431 public function initialize($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000432 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200433 // Convert array elements into class variables
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 if (count($props) > 0)
435 {
436 foreach ($props as $key => $val)
437 {
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200438 if (property_exists($this, $key))
439 {
440 if (in_array($key, array('wm_font_color', 'wm_shadow_color')))
441 {
Andrey Andreev8323ae62011-12-31 18:39:10 +0200442 if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200443 {
Andrey Andreevcf2ba9e2012-01-01 21:57:13 +0200444 /* $matches[1] contains our hex color value, but it might be
Andrey Andreev8323ae62011-12-31 18:39:10 +0200445 * both in the full 6-length format or the shortened 3-length
446 * value.
Andrey Andreevbb96c8b2011-12-31 18:48:39 +0200447 * We'll later need the full version, so we keep it if it's
Andrey Andreev8323ae62011-12-31 18:39:10 +0200448 * already there and if not - we'll convert to it. We can
449 * access string characters by their index as in an array,
450 * so we'll do that and use concatenation to form the final
451 * value:
452 */
Andrey Andreev665af0c2011-12-30 14:39:29 +0200453 $val = (strlen($matches[1]) === 6)
454 ? '#'.$matches[1]
455 : '#'.$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 +0200456 }
457 else
458 {
459 continue;
460 }
461 }
462
463 $this->$key = $val;
464 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 }
466 }
467
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200468 // Is there a source image? If not, there's no reason to continue
Alex Bilbied261b1e2012-06-02 11:12:16 +0100469 if ($this->source_image === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 {
471 $this->set_error('imglib_source_image_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500472 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 }
474
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200475 /* Is getimagesize() available?
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 *
477 * We use it to determine the image properties (width/height).
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200478 * Note: We need to figure out how to determine image
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 * properties using ImageMagick and NetPBM
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 */
481 if ( ! function_exists('getimagesize'))
482 {
483 $this->set_error('imglib_gd_required_for_props');
484 return FALSE;
485 }
486
487 $this->image_library = strtolower($this->image_library);
488
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200489 /* Set the full server path
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 *
491 * The source image may or may not contain a path.
492 * Either way, we'll try use realpath to generate the
493 * full server path in order to more reliably read it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000494 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200495 if (function_exists('realpath') && @realpath($this->source_image) !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000496 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200497 $full_source_path = str_replace('\\', '/', realpath($this->source_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000498 }
499 else
500 {
501 $full_source_path = $this->source_image;
502 }
503
504 $x = explode('/', $full_source_path);
505 $this->source_image = end($x);
506 $this->source_folder = str_replace($this->source_image, '', $full_source_path);
507
508 // Set the Image Properties
509 if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
510 {
Eric Barnesb1673362011-12-05 22:05:38 -0500511 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 }
513
514 /*
515 * Assign the "new" image name/path
516 *
517 * If the user has set a "new_image" name it means
518 * we are making a copy of the source image. If not
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200519 * it means we are altering the original. We'll
Derek Allard2067d1a2008-11-13 22:59:24 +0000520 * set the destination filename and path accordingly.
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100522 if ($this->new_image === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 {
524 $this->dest_image = $this->source_image;
525 $this->dest_folder = $this->source_folder;
526 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200527 elseif (strpos($this->new_image, '/') === FALSE)
528 {
529 $this->dest_folder = $this->source_folder;
530 $this->dest_image = $this->new_image;
531 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000532 else
533 {
Andrey Andreev1b815532012-04-03 16:06:03 +0300534 if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000535 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200536 $full_dest_path = str_replace('\\', '/', realpath($this->new_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000537 }
538 else
539 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200540 $full_dest_path = $this->new_image;
541 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000542
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200543 // Is there a file name?
544 if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path))
545 {
546 $this->dest_folder = $full_dest_path.'/';
547 $this->dest_image = $this->source_image;
548 }
549 else
550 {
551 $x = explode('/', $full_dest_path);
552 $this->dest_image = end($x);
553 $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000554 }
555 }
556
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200557 /* Compile the finalized filenames/paths
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 *
559 * We'll create two master strings containing the
560 * full server path to the source image and the
561 * full server path to the destination image.
562 * We'll also split the destination image name
563 * so we can insert the thumbnail marker if needed.
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100565 if ($this->create_thumb === FALSE OR $this->thumb_marker === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000566 {
567 $this->thumb_marker = '';
568 }
569
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200570 $xp = $this->explode_name($this->dest_image);
Derek Allard2067d1a2008-11-13 22:59:24 +0000571
572 $filename = $xp['name'];
573 $file_ext = $xp['ext'];
574
575 $this->full_src_path = $this->source_folder.$this->source_image;
576 $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
577
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200578 /* Should we maintain image proportions?
Derek Allard2067d1a2008-11-13 22:59:24 +0000579 *
580 * When creating thumbs or copies, the target width/height
581 * might not be in correct proportion with the source
Andrey Andreev8e70b792012-01-12 20:19:24 +0200582 * image's width/height. We'll recalculate it here.
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100584 if ($this->maintain_ratio === TRUE && ($this->width !== 0 OR $this->height !== 0))
Derek Allard2067d1a2008-11-13 22:59:24 +0000585 {
586 $this->image_reproportion();
587 }
588
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200589 /* Was a width and height specified?
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 *
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200591 * If the destination width/height was not submitted we
592 * will use the values from the actual file
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100594 if ($this->width === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200595 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000596 $this->width = $this->orig_width;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200597 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000598
Alex Bilbied261b1e2012-06-02 11:12:16 +0100599 if ($this->height === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200600 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000601 $this->height = $this->orig_height;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200602 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000603
604 // Set the quality
Andrey Andreev8e70b792012-01-12 20:19:24 +0200605 $this->quality = trim(str_replace('%', '', $this->quality));
Derek Allard2067d1a2008-11-13 22:59:24 +0000606
Alex Bilbied261b1e2012-06-02 11:12:16 +0100607 if ($this->quality === '' OR $this->quality === 0 OR ! preg_match('/^[0-9]+$/', $this->quality))
Andrey Andreev8e70b792012-01-12 20:19:24 +0200608 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000609 $this->quality = 90;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200610 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000611
612 // Set the x/y coordinates
Andrey Andreev5036c9c2012-06-04 15:34:56 +0300613 is_numeric($this->x_axis) OR $this->x_axis = 0;
614 is_numeric($this->y_axis) OR $this->y_axis = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +0000615
616 // Watermark-related Stuff...
Alex Bilbied261b1e2012-06-02 11:12:16 +0100617 if ($this->wm_overlay_path !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000618 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200619 $this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
Derek Allard2067d1a2008-11-13 22:59:24 +0000620 }
621
Alex Bilbied261b1e2012-06-02 11:12:16 +0100622 if ($this->wm_shadow_color !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000623 {
624 $this->wm_use_drop_shadow = TRUE;
625 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100626 elseif ($this->wm_use_drop_shadow === TRUE && $this->wm_shadow_color === '')
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200627 {
628 $this->wm_use_drop_shadow = FALSE;
629 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000630
Alex Bilbied261b1e2012-06-02 11:12:16 +0100631 if ($this->wm_font_path !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000632 {
633 $this->wm_use_truetype = TRUE;
634 }
635
636 return TRUE;
637 }
638
639 // --------------------------------------------------------------------
640
641 /**
642 * Image Resize
643 *
644 * This is a wrapper function that chooses the proper
645 * resize function based on the protocol specified
646 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000647 * @return bool
648 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200649 public function resize()
Derek Allard2067d1a2008-11-13 22:59:24 +0000650 {
Andrey Andreev1a9f52c2012-01-07 01:06:34 +0200651 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000652 return $this->$protocol('resize');
653 }
654
655 // --------------------------------------------------------------------
656
657 /**
658 * Image Crop
659 *
660 * This is a wrapper function that chooses the proper
661 * cropping function based on the protocol specified
662 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000663 * @return bool
664 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200665 public function crop()
Derek Allard2067d1a2008-11-13 22:59:24 +0000666 {
Andrey Andreev5a67e3d2012-01-07 01:21:09 +0200667 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000668 return $this->$protocol('crop');
669 }
670
671 // --------------------------------------------------------------------
672
673 /**
674 * Image Rotate
675 *
676 * This is a wrapper function that chooses the proper
677 * rotation function based on the protocol specified
678 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 * @return bool
680 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200681 public function rotate()
Derek Allard2067d1a2008-11-13 22:59:24 +0000682 {
683 // Allowed rotation values
684 $degs = array(90, 180, 270, 'vrt', 'hor');
685
Alex Bilbied261b1e2012-06-02 11:12:16 +0100686 if ($this->rotation_angle === '' OR ! in_array($this->rotation_angle, $degs))
Derek Allard2067d1a2008-11-13 22:59:24 +0000687 {
688 $this->set_error('imglib_rotation_angle_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500689 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000690 }
691
692 // Reassign the width and height
Alex Bilbied261b1e2012-06-02 11:12:16 +0100693 if ($this->rotation_angle === 90 OR $this->rotation_angle === 270)
Derek Allard2067d1a2008-11-13 22:59:24 +0000694 {
695 $this->width = $this->orig_height;
696 $this->height = $this->orig_width;
697 }
698 else
699 {
700 $this->width = $this->orig_width;
701 $this->height = $this->orig_height;
702 }
703
Derek Allard2067d1a2008-11-13 22:59:24 +0000704 // Choose resizing function
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200705 if ($this->image_library === 'imagemagick' OR $this->image_library === 'netpbm')
Derek Allard2067d1a2008-11-13 22:59:24 +0000706 {
707 $protocol = 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000708 return $this->$protocol('rotate');
709 }
710
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200711 return ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
712 ? $this->image_mirror_gd()
713 : $this->image_rotate_gd();
Derek Allard2067d1a2008-11-13 22:59:24 +0000714 }
715
716 // --------------------------------------------------------------------
717
718 /**
719 * Image Process Using GD/GD2
720 *
721 * This function will resize or crop
722 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000723 * @param string
724 * @return bool
725 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200726 public function image_process_gd($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000727 {
728 $v2_override = FALSE;
729
730 // If the target width/height match the source, AND if the new file name is not equal to the old file name
731 // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
Alex Bilbied261b1e2012-06-02 11:12:16 +0100732 if ($this->dynamic_output === FALSE && $this->orig_width === $this->width && $this->orig_height === $this->height)
Derek Allard2067d1a2008-11-13 22:59:24 +0000733 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100734 if ($this->source_image !== $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000735 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200736 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000737 }
Andrey Andreeva92b9032011-12-24 19:05:58 +0200738
739 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000740 }
741
742 // Let's set up our values based on the action
Alex Bilbied261b1e2012-06-02 11:12:16 +0100743 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000744 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200745 // Reassign the source width/height if cropping
Derek Jones4b9c6292011-07-01 17:40:48 -0500746 $this->orig_width = $this->width;
Derek Allard2067d1a2008-11-13 22:59:24 +0000747 $this->orig_height = $this->height;
748
749 // GD 2.0 has a cropping bug so we'll test for it
750 if ($this->gd_version() !== FALSE)
751 {
752 $gd_version = str_replace('0', '', $this->gd_version());
Andrey Andreev5036c9c2012-06-04 15:34:56 +0300753 $v2_override = ($gd_version === 2);
Derek Allard2067d1a2008-11-13 22:59:24 +0000754 }
755 }
756 else
757 {
758 // If resizing the x/y axis must be zero
759 $this->x_axis = 0;
760 $this->y_axis = 0;
761 }
762
Derek Jones4b9c6292011-07-01 17:40:48 -0500763 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000764 if ( ! ($src_img = $this->image_create_gd()))
765 {
766 return FALSE;
767 }
768
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200769 /* Create the image
770 *
771 * Old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
772 * it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
773 * below should that ever prove inaccurate.
774 *
Alex Bilbied261b1e2012-06-02 11:12:16 +0100775 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override === FALSE)
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200776 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200777 if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000778 {
779 $create = 'imagecreatetruecolor';
780 $copy = 'imagecopyresampled';
781 }
782 else
783 {
784 $create = 'imagecreate';
785 $copy = 'imagecopyresized';
786 }
787
788 $dst_img = $create($this->width, $this->height);
Derek Jones595bfd12010-08-20 10:28:22 -0500789
Alex Bilbied261b1e2012-06-02 11:12:16 +0100790 if ($this->image_type === 3) // png we can actually preserve transparency
Derek Jones595bfd12010-08-20 10:28:22 -0500791 {
792 imagealphablending($dst_img, FALSE);
793 imagesavealpha($dst_img, TRUE);
794 }
Barry Mienydd671972010-10-04 16:33:58 +0200795
Derek Allard2067d1a2008-11-13 22:59:24 +0000796 $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
797
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200798 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +0100799 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000800 {
801 $this->image_display_gd($dst_img);
802 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200803 elseif ( ! $this->image_save_gd($dst_img)) // Or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000804 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200805 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000806 }
807
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200808 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000809 imagedestroy($dst_img);
810 imagedestroy($src_img);
811
812 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000813 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000814
815 return TRUE;
816 }
817
818 // --------------------------------------------------------------------
819
820 /**
821 * Image Process Using ImageMagick
822 *
823 * This function will resize, crop or rotate
824 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000825 * @param string
826 * @return bool
827 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200828 public function image_process_imagemagick($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000829 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500830 // Do we have a vaild library path?
Alex Bilbied261b1e2012-06-02 11:12:16 +0100831 if ($this->library_path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000832 {
833 $this->set_error('imglib_libpath_invalid');
834 return FALSE;
835 }
836
Andrey Andreev8e70b792012-01-12 20:19:24 +0200837 if ( ! preg_match('/convert$/i', $this->library_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000838 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200839 $this->library_path = rtrim($this->library_path, '/').'/convert';
Derek Allard2067d1a2008-11-13 22:59:24 +0000840 }
841
842 // Execute the command
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200843 $cmd = $this->library_path.' -quality '.$this->quality;
Derek Allard2067d1a2008-11-13 22:59:24 +0000844
Alex Bilbied261b1e2012-06-02 11:12:16 +0100845 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000846 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200847 $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 +0000848 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100849 elseif ($action === 'rotate')
Derek Allard2067d1a2008-11-13 22:59:24 +0000850 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200851 $angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
852 ? '-flop' : '-rotate '.$this->rotation_angle;
Derek Allard2067d1a2008-11-13 22:59:24 +0000853
Andrey Andreev8e70b792012-01-12 20:19:24 +0200854 $cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000855 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200856 else // Resize
Derek Allard2067d1a2008-11-13 22:59:24 +0000857 {
Omar24063af2012-07-02 13:50:17 -0300858 if($this->maintain_ratio === TRUE)
859 {
860 $cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
861 }
Omarbb531d62012-06-29 10:48:28 -0300862 else
Omar24063af2012-07-02 13:50:17 -0300863 {
864 $cmd .= ' -resize '.$this->width.'x'.$this->height.'\! "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
865 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000866 }
867
868 $retval = 1;
Derek Allard2067d1a2008-11-13 22:59:24 +0000869 @exec($cmd, $output, $retval);
870
Andrey Andreev8e70b792012-01-12 20:19:24 +0200871 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000872 if ($retval > 0)
873 {
874 $this->set_error('imglib_image_process_failed');
875 return FALSE;
876 }
877
878 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000879 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000880
881 return TRUE;
882 }
883
884 // --------------------------------------------------------------------
885
886 /**
887 * Image Process Using NetPBM
888 *
889 * This function will resize, crop or rotate
890 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000891 * @param string
892 * @return bool
893 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200894 public function image_process_netpbm($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000895 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100896 if ($this->library_path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000897 {
898 $this->set_error('imglib_libpath_invalid');
899 return FALSE;
900 }
901
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200902 // Build the resizing command
Derek Allard2067d1a2008-11-13 22:59:24 +0000903 switch ($this->image_type)
904 {
905 case 1 :
Andrey Andreev56454792012-05-17 14:32:19 +0300906 $cmd_in = 'giftopnm';
907 $cmd_out = 'ppmtogif';
Derek Allard2067d1a2008-11-13 22:59:24 +0000908 break;
909 case 2 :
Andrey Andreev56454792012-05-17 14:32:19 +0300910 $cmd_in = 'jpegtopnm';
911 $cmd_out = 'ppmtojpeg';
Derek Allard2067d1a2008-11-13 22:59:24 +0000912 break;
913 case 3 :
Andrey Andreev56454792012-05-17 14:32:19 +0300914 $cmd_in = 'pngtopnm';
915 $cmd_out = 'ppmtopng';
Derek Allard2067d1a2008-11-13 22:59:24 +0000916 break;
917 }
918
Alex Bilbied261b1e2012-06-02 11:12:16 +0100919 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000920 {
921 $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
922 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100923 elseif ($action === 'rotate')
Derek Allard2067d1a2008-11-13 22:59:24 +0000924 {
925 switch ($this->rotation_angle)
926 {
Andrey Andreev56454792012-05-17 14:32:19 +0300927 case 90: $angle = 'r270';
Derek Allard2067d1a2008-11-13 22:59:24 +0000928 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300929 case 180: $angle = 'r180';
Derek Allard2067d1a2008-11-13 22:59:24 +0000930 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300931 case 270: $angle = 'r90';
Derek Allard2067d1a2008-11-13 22:59:24 +0000932 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300933 case 'vrt': $angle = 'tb';
Derek Allard2067d1a2008-11-13 22:59:24 +0000934 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300935 case 'hor': $angle = 'lr';
Derek Allard2067d1a2008-11-13 22:59:24 +0000936 break;
937 }
938
939 $cmd_inner = 'pnmflip -'.$angle.' ';
940 }
941 else // Resize
942 {
943 $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
944 }
945
946 $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
947
948 $retval = 1;
Derek Allard2067d1a2008-11-13 22:59:24 +0000949 @exec($cmd, $output, $retval);
950
Andrey Andreev8e70b792012-01-12 20:19:24 +0200951 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000952 if ($retval > 0)
953 {
954 $this->set_error('imglib_image_process_failed');
955 return FALSE;
956 }
957
958 // With NetPBM we have to create a temporary image.
959 // If you try manipulating the original it fails so
960 // we have to rename the temp file.
961 copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200962 unlink($this->dest_folder.'netpbm.tmp');
Derek Jones172e1612009-10-13 14:32:48 +0000963 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000964
965 return TRUE;
966 }
967
968 // --------------------------------------------------------------------
969
970 /**
971 * Image Rotate Using GD
972 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000973 * @return bool
974 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200975 public function image_rotate_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +0000976 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200977 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000978 if ( ! ($src_img = $this->image_create_gd()))
979 {
980 return FALSE;
981 }
982
983 // Set the background color
984 // This won't work with transparent PNG files so we are
985 // going to have to figure out how to determine the color
986 // of the alpha channel in a future release.
987
988 $white = imagecolorallocate($src_img, 255, 255, 255);
989
Andrey Andreev8e70b792012-01-12 20:19:24 +0200990 // Rotate it!
Derek Allard2067d1a2008-11-13 22:59:24 +0000991 $dst_img = imagerotate($src_img, $this->rotation_angle, $white);
992
Andrey Andreev8e70b792012-01-12 20:19:24 +0200993 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +0100994 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000995 {
996 $this->image_display_gd($dst_img);
997 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200998 elseif ( ! $this->image_save_gd($dst_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000999 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001000 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001001 }
1002
Andrey Andreev8e70b792012-01-12 20:19:24 +02001003 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001004 imagedestroy($dst_img);
1005 imagedestroy($src_img);
1006
1007 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +00001008 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001009
Pascal Kriete8761ef52011-02-14 13:13:52 -05001010 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001011 }
1012
1013 // --------------------------------------------------------------------
1014
1015 /**
1016 * Create Mirror Image using GD
1017 *
1018 * This function will flip horizontal or vertical
1019 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001020 * @return bool
1021 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001022 public function image_mirror_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +00001023 {
1024 if ( ! $src_img = $this->image_create_gd())
1025 {
1026 return FALSE;
1027 }
1028
Derek Jones4b9c6292011-07-01 17:40:48 -05001029 $width = $this->orig_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001030 $height = $this->orig_height;
1031
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001032 if ($this->rotation_angle === 'hor')
Derek Allard2067d1a2008-11-13 22:59:24 +00001033 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001034 for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001035 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001036 while ($left < $right)
1037 {
1038 $cl = imagecolorat($src_img, $left, $i);
1039 $cr = imagecolorat($src_img, $right, $i);
1040
1041 imagesetpixel($src_img, $left, $i, $cr);
1042 imagesetpixel($src_img, $right, $i, $cl);
1043
1044 $left++;
1045 $right--;
1046 }
1047 }
1048 }
1049 else
1050 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001051 for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001052 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001053 while ($top < $bot)
1054 {
1055 $ct = imagecolorat($src_img, $i, $top);
1056 $cb = imagecolorat($src_img, $i, $bot);
1057
1058 imagesetpixel($src_img, $i, $top, $cb);
1059 imagesetpixel($src_img, $i, $bot, $ct);
1060
1061 $top++;
1062 $bot--;
1063 }
1064 }
1065 }
1066
Andrey Andreev8e70b792012-01-12 20:19:24 +02001067 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001068 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001069 {
1070 $this->image_display_gd($src_img);
1071 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001072 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001073 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001074 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001075 }
1076
Andrey Andreev8e70b792012-01-12 20:19:24 +02001077 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001078 imagedestroy($src_img);
1079
1080 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +00001081 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001082
1083 return TRUE;
1084 }
1085
1086 // --------------------------------------------------------------------
1087
1088 /**
1089 * Image Watermark
1090 *
1091 * This is a wrapper function that chooses the type
1092 * of watermarking based on the specified preference.
1093 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001094 * @return bool
1095 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001096 public function watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001097 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001098 return ($this->wm_type === 'overlay') ? $this->overlay_watermark() : $this->text_watermark();
Derek Allard2067d1a2008-11-13 22:59:24 +00001099 }
1100
1101 // --------------------------------------------------------------------
1102
1103 /**
1104 * Watermark - Graphic Version
1105 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001106 * @return bool
1107 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001108 public function overlay_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001109 {
1110 if ( ! function_exists('imagecolortransparent'))
1111 {
1112 $this->set_error('imglib_gd_required');
1113 return FALSE;
1114 }
1115
Andrey Andreev8e70b792012-01-12 20:19:24 +02001116 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001117 $this->get_image_properties();
1118
Andrey Andreev8e70b792012-01-12 20:19:24 +02001119 // Fetch watermark image properties
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001120 $props = $this->get_image_properties($this->wm_overlay_path, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001121 $wm_img_type = $props['image_type'];
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001122 $wm_width = $props['width'];
1123 $wm_height = $props['height'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001124
Andrey Andreev8e70b792012-01-12 20:19:24 +02001125 // Create two image resources
Derek Jones4b9c6292011-07-01 17:40:48 -05001126 $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001127 $src_img = $this->image_create_gd($this->full_src_path);
1128
1129 // Reverse the offset if necessary
1130 // When the image is positioned at the bottom
1131 // we don't want the vertical offset to push it
Andrey Andreev8e70b792012-01-12 20:19:24 +02001132 // further down. We want the reverse, so we'll
1133 // invert the offset. Same with the horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001134 // offset when the image is at the right
1135
Andrey Andreev8e70b792012-01-12 20:19:24 +02001136 $this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
1137 $this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001138
Alex Bilbied261b1e2012-06-02 11:12:16 +01001139 if ($this->wm_vrt_alignment === 'B')
Derek Allard2067d1a2008-11-13 22:59:24 +00001140 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1141
Alex Bilbied261b1e2012-06-02 11:12:16 +01001142 if ($this->wm_hor_alignment === 'R')
Derek Allard2067d1a2008-11-13 22:59:24 +00001143 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1144
Andrey Andreev8e70b792012-01-12 20:19:24 +02001145 // Set the base x and y axis values
Derek Allard2067d1a2008-11-13 22:59:24 +00001146 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1147 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1148
Andrey Andreev8e70b792012-01-12 20:19:24 +02001149 // Set the vertical position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001150 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001151 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001152 $y_axis += ($this->orig_height / 2) - ($wm_height / 2);
1153 }
1154 elseif ($this->wm_vrt_alignment === 'B')
1155 {
1156 $y_axis += $this->orig_height - $wm_height;
Derek Allard2067d1a2008-11-13 22:59:24 +00001157 }
1158
Andrey Andreev8e70b792012-01-12 20:19:24 +02001159 // Set the horizontal position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001160 if ($this->wm_hor_alignment === 'C')
Derek Allard2067d1a2008-11-13 22:59:24 +00001161 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001162 $x_axis += ($this->orig_width / 2) - ($wm_width / 2);
1163 }
1164 elseif ($this->wm_hor_alignment === 'R')
1165 {
1166 $x_axis += $this->orig_width - $wm_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001167 }
1168
Derek Jones4b9c6292011-07-01 17:40:48 -05001169 // Build the finalized image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001170 if ($wm_img_type === 3 && function_exists('imagealphablending'))
Derek Allard2067d1a2008-11-13 22:59:24 +00001171 {
1172 @imagealphablending($src_img, TRUE);
Barry Mienydd671972010-10-04 16:33:58 +02001173 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001174
1175 // Set RGB values for text and shadow
1176 $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
1177 $alpha = ($rgba & 0x7F000000) >> 24;
1178
1179 // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1180 if ($alpha > 0)
1181 {
1182 // copy the image directly, the image's alpha transparency being the sole determinant of blending
1183 imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
1184 }
1185 else
1186 {
1187 // set our RGB value from above to be transparent and merge the images with the specified opacity
1188 imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
1189 imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
1190 }
1191
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001192 // Output the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001193 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001194 {
1195 $this->image_display_gd($src_img);
1196 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001197 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001198 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001199 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001200 }
1201
1202 imagedestroy($src_img);
1203 imagedestroy($wm_img);
1204
1205 return TRUE;
1206 }
1207
1208 // --------------------------------------------------------------------
1209
1210 /**
1211 * Watermark - Text Version
1212 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001213 * @return bool
1214 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001215 public function text_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001216 {
1217 if ( ! ($src_img = $this->image_create_gd()))
1218 {
1219 return FALSE;
1220 }
1221
Alex Bilbied261b1e2012-06-02 11:12:16 +01001222 if ($this->wm_use_truetype === TRUE && ! file_exists($this->wm_font_path))
Derek Allard2067d1a2008-11-13 22:59:24 +00001223 {
1224 $this->set_error('imglib_missing_font');
1225 return FALSE;
1226 }
1227
Andrey Andreev8e70b792012-01-12 20:19:24 +02001228 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001229 $this->get_image_properties();
1230
Derek Allard2067d1a2008-11-13 22:59:24 +00001231 // Reverse the vertical offset
1232 // When the image is positioned at the bottom
1233 // we don't want the vertical offset to push it
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001234 // further down. We want the reverse, so we'll
Andrey Andreev8e70b792012-01-12 20:19:24 +02001235 // invert the offset. Note: The horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001236 // offset flips itself automatically
1237
Alex Bilbied261b1e2012-06-02 11:12:16 +01001238 if ($this->wm_vrt_alignment === 'B')
Derek Allard2067d1a2008-11-13 22:59:24 +00001239 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1240
Alex Bilbied261b1e2012-06-02 11:12:16 +01001241 if ($this->wm_hor_alignment === 'R')
Derek Allard2067d1a2008-11-13 22:59:24 +00001242 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1243
1244 // Set font width and height
1245 // These are calculated differently depending on
1246 // whether we are using the true type font or not
Alex Bilbied261b1e2012-06-02 11:12:16 +01001247 if ($this->wm_use_truetype === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001248 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001249 if ($this->wm_font_size === '')
Andrey Andreeva92b9032011-12-24 19:05:58 +02001250 {
1251 $this->wm_font_size = 17;
1252 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001253
Derek Jones4b9c6292011-07-01 17:40:48 -05001254 $fontwidth = $this->wm_font_size-($this->wm_font_size/4);
Derek Allard2067d1a2008-11-13 22:59:24 +00001255 $fontheight = $this->wm_font_size;
1256 $this->wm_vrt_offset += $this->wm_font_size;
1257 }
1258 else
1259 {
Derek Jones4b9c6292011-07-01 17:40:48 -05001260 $fontwidth = imagefontwidth($this->wm_font_size);
Derek Allard2067d1a2008-11-13 22:59:24 +00001261 $fontheight = imagefontheight($this->wm_font_size);
1262 }
1263
1264 // Set base X and Y axis values
1265 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1266 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1267
Alex Bilbied261b1e2012-06-02 11:12:16 +01001268 if ($this->wm_use_drop_shadow === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001269 $this->wm_shadow_distance = 0;
1270
1271 $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
1272 $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
1273
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001274 // Set verticle alignment
1275 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001276 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001277 $y_axis += ($this->orig_height / 2) + ($fontheight / 2);
1278 }
1279 elseif ($this->wm_vrt_alignment === 'B')
1280 {
1281 $y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2);
Derek Allard2067d1a2008-11-13 22:59:24 +00001282 }
1283
1284 $x_shad = $x_axis + $this->wm_shadow_distance;
1285 $y_shad = $y_axis + $this->wm_shadow_distance;
1286
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001287 if ($this->wm_use_drop_shadow)
Derek Allard2067d1a2008-11-13 22:59:24 +00001288 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001289 // Set horizontal alignment
1290 if ($this->wm_hor_alignment === 'R')
1291 {
1292 $x_shad += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1293 $x_axis += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1294 }
1295 elseif ($this->wm_hor_alignment === 'C')
1296 {
1297 $x_shad += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1298 $x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1299 }
1300
Andrey Andreev8323ae62011-12-31 18:39:10 +02001301 /* Set RGB values for text and shadow
1302 *
1303 * First character is #, so we don't really need it.
1304 * Get the rest of the string and split it into 2-length
1305 * hex values:
1306 */
1307 $txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001308 $txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
Andrey Andreev8323ae62011-12-31 18:39:10 +02001309 $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
Ronald Beilsma8f80bc42012-01-12 16:41:49 +01001310 $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001311
Andrey Andreev8e70b792012-01-12 20:19:24 +02001312 // Add the text to the source image
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001313 if ($this->wm_use_truetype)
1314 {
1315 imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
1316 imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
1317 }
1318 else
1319 {
1320 imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
1321 imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
1322 }
Andrey Andreev99ae2262012-10-05 15:14:30 +03001323
1324 // We can preserve transparency for PNG images
1325 if ($this->image_type === 3)
1326 {
1327 imagealphablending($src_img, FALSE);
1328 imagesavealpha($src_img, TRUE);
1329 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001330 }
1331
Andrey Andreev8e70b792012-01-12 20:19:24 +02001332 // Output the final image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001333 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001334 {
1335 $this->image_display_gd($src_img);
1336 }
1337 else
1338 {
1339 $this->image_save_gd($src_img);
1340 }
1341
1342 imagedestroy($src_img);
1343
1344 return TRUE;
1345 }
1346
1347 // --------------------------------------------------------------------
1348
1349 /**
1350 * Create Image - GD
1351 *
1352 * This simply creates an image resource handle
1353 * based on the type of image being processed
1354 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001355 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001356 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001357 * @return resource
1358 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001359 public function image_create_gd($path = '', $image_type = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001360 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001361 if ($path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001362 $path = $this->full_src_path;
1363
Alex Bilbied261b1e2012-06-02 11:12:16 +01001364 if ($image_type === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001365 $image_type = $this->image_type;
1366
1367
1368 switch ($image_type)
1369 {
1370 case 1 :
1371 if ( ! function_exists('imagecreatefromgif'))
1372 {
1373 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1374 return FALSE;
1375 }
1376
1377 return imagecreatefromgif($path);
1378 break;
1379 case 2 :
1380 if ( ! function_exists('imagecreatefromjpeg'))
1381 {
1382 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1383 return FALSE;
1384 }
1385
1386 return imagecreatefromjpeg($path);
1387 break;
1388 case 3 :
1389 if ( ! function_exists('imagecreatefrompng'))
1390 {
1391 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1392 return FALSE;
1393 }
1394
1395 return imagecreatefrompng($path);
1396 break;
1397
1398 }
1399
1400 $this->set_error(array('imglib_unsupported_imagecreate'));
1401 return FALSE;
1402 }
1403
1404 // --------------------------------------------------------------------
1405
1406 /**
1407 * Write image file to disk - GD
1408 *
1409 * Takes an image resource as input and writes the file
1410 * to the specified destination
1411 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001412 * @param resource
1413 * @return bool
1414 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001415 public function image_save_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001416 {
1417 switch ($this->image_type)
1418 {
Andrey Andreev56454792012-05-17 14:32:19 +03001419 case 1:
1420 if ( ! function_exists('imagegif'))
1421 {
1422 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1423 return FALSE;
1424 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001425
Andrey Andreev56454792012-05-17 14:32:19 +03001426 if ( ! @imagegif($resource, $this->full_dst_path))
1427 {
1428 $this->set_error('imglib_save_failed');
1429 return FALSE;
1430 }
1431 break;
1432 case 2:
1433 if ( ! function_exists('imagejpeg'))
1434 {
1435 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1436 return FALSE;
1437 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001438
Andrey Andreev56454792012-05-17 14:32:19 +03001439 if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
1440 {
1441 $this->set_error('imglib_save_failed');
1442 return FALSE;
1443 }
1444 break;
1445 case 3:
1446 if ( ! function_exists('imagepng'))
1447 {
1448 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1449 return FALSE;
1450 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001451
Andrey Andreev56454792012-05-17 14:32:19 +03001452 if ( ! @imagepng($resource, $this->full_dst_path))
1453 {
1454 $this->set_error('imglib_save_failed');
1455 return FALSE;
1456 }
1457 break;
1458 default:
1459 $this->set_error(array('imglib_unsupported_imagecreate'));
1460 return FALSE;
1461 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001462 }
1463
1464 return TRUE;
1465 }
1466
1467 // --------------------------------------------------------------------
1468
1469 /**
1470 * Dynamically outputs an image
1471 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001472 * @param resource
1473 * @return void
1474 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001475 public function image_display_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001476 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001477 header('Content-Disposition: filename='.$this->source_image.';');
1478 header('Content-Type: '.$this->mime_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001479 header('Content-Transfer-Encoding: binary');
1480 header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
1481
1482 switch ($this->image_type)
1483 {
Andrey Andreev56454792012-05-17 14:32:19 +03001484 case 1 : imagegif($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001485 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001486 case 2 : imagejpeg($resource, '', $this->quality);
Derek Allard2067d1a2008-11-13 22:59:24 +00001487 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001488 case 3 : imagepng($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001489 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001490 default: echo 'Unable to display the image';
Derek Allard2067d1a2008-11-13 22:59:24 +00001491 break;
1492 }
1493 }
1494
1495 // --------------------------------------------------------------------
1496
1497 /**
1498 * Re-proportion Image Width/Height
1499 *
1500 * When creating thumbs, the desired width/height
1501 * can end up warping the image due to an incorrect
1502 * ratio between the full-sized image and the thumb.
1503 *
1504 * This function lets us re-proportion the width/height
1505 * if users choose to maintain the aspect ratio when resizing.
1506 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001507 * @return void
1508 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001509 public function image_reproportion()
Derek Allard2067d1a2008-11-13 22:59:24 +00001510 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001511 if (($this->width === 0 && $this->height === 0) OR $this->orig_width === 0 OR $this->orig_height === 0
Andrey Andreev8e70b792012-01-12 20:19:24 +02001512 OR ( ! preg_match('/^[0-9]+$/', $this->width) && ! preg_match('/^[0-9]+$/', $this->height))
1513 OR ! preg_match('/^[0-9]+$/', $this->orig_width) OR ! preg_match('/^[0-9]+$/', $this->orig_height))
Derek Allard2067d1a2008-11-13 22:59:24 +00001514 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001515 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001516 }
1517
Andrey Andreev8e70b792012-01-12 20:19:24 +02001518 // Sanitize so we don't call preg_match() anymore
1519 $this->width = (int) $this->width;
1520 $this->height = (int) $this->height;
1521
1522 if ($this->master_dim !== 'width' && $this->master_dim !== 'height')
Derek Allard2067d1a2008-11-13 22:59:24 +00001523 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001524 if ($this->width > 0 && $this->height > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001525 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001526 $this->master_dim = ((($this->orig_height/$this->orig_width) - ($this->height/$this->width)) < 0)
1527 ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001528 }
1529 else
1530 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001531 $this->master_dim = ($this->height === 0) ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001532 }
1533 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001534 elseif (($this->master_dim === 'width' && $this->width === 0)
1535 OR ($this->master_dim === 'height' && $this->height === 0))
1536 {
1537 return;
1538 }
1539
1540 if ($this->master_dim === 'width')
1541 {
1542 $this->height = (int) ceil($this->width*$this->orig_height/$this->orig_width);
1543 }
1544 else
1545 {
1546 $this->width = (int) ceil($this->orig_width*$this->height/$this->orig_height);
1547 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001548 }
1549
1550 // --------------------------------------------------------------------
1551
1552 /**
1553 * Get image properties
1554 *
1555 * A helper function that gets info about the file
1556 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001557 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001558 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001559 * @return mixed
1560 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001561 public function get_image_properties($path = '', $return = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001562 {
1563 // For now we require GD but we should
1564 // find a way to determine this using IM or NetPBM
1565
Alex Bilbied261b1e2012-06-02 11:12:16 +01001566 if ($path === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +02001567 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001568 $path = $this->full_src_path;
Andrey Andreev8e70b792012-01-12 20:19:24 +02001569 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001570
1571 if ( ! file_exists($path))
1572 {
1573 $this->set_error('imglib_invalid_path');
1574 return FALSE;
1575 }
1576
Phil Sturgeon901998a2011-08-26 10:03:33 +01001577 $vals = getimagesize($path);
Derek Allard2067d1a2008-11-13 22:59:24 +00001578 $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
Andrey Andreeva92b9032011-12-24 19:05:58 +02001579 $mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001580
Alex Bilbied261b1e2012-06-02 11:12:16 +01001581 if ($return === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001582 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001583 return array(
1584 'width' => $vals[0],
1585 'height' => $vals[1],
1586 'image_type' => $vals[2],
1587 'size_str' => $vals[3],
1588 'mime_type' => $mime
1589 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001590 }
1591
Andrey Andreeva92b9032011-12-24 19:05:58 +02001592 $this->orig_width = $vals[0];
1593 $this->orig_height = $vals[1];
1594 $this->image_type = $vals[2];
1595 $this->size_str = $vals[3];
Derek Allard2067d1a2008-11-13 22:59:24 +00001596 $this->mime_type = $mime;
1597
1598 return TRUE;
1599 }
1600
1601 // --------------------------------------------------------------------
1602
1603 /**
1604 * Size calculator
1605 *
1606 * This function takes a known width x height and
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001607 * recalculates it to a new size. Only one
Derek Allard2067d1a2008-11-13 22:59:24 +00001608 * new variable needs to be known
1609 *
1610 * $props = array(
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001611 * 'width' => $width,
1612 * 'height' => $height,
1613 * 'new_width' => 40,
1614 * 'new_height' => ''
1615 * );
Derek Allard2067d1a2008-11-13 22:59:24 +00001616 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001617 * @param array
1618 * @return array
1619 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001620 public function size_calculator($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001621 {
1622 if ( ! is_array($vals))
1623 {
1624 return;
1625 }
1626
1627 $allowed = array('new_width', 'new_height', 'width', 'height');
1628
1629 foreach ($allowed as $item)
1630 {
Andrey Andreev56454792012-05-17 14:32:19 +03001631 if (empty($vals[$item]))
1632 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001633 $vals[$item] = 0;
Andrey Andreev56454792012-05-17 14:32:19 +03001634 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001635 }
1636
Alex Bilbied261b1e2012-06-02 11:12:16 +01001637 if ($vals['width'] === 0 OR $vals['height'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001638 {
1639 return $vals;
1640 }
1641
Alex Bilbied261b1e2012-06-02 11:12:16 +01001642 if ($vals['new_width'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001643 {
1644 $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1645 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001646 elseif ($vals['new_height'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001647 {
1648 $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1649 }
1650
1651 return $vals;
1652 }
1653
1654 // --------------------------------------------------------------------
1655
1656 /**
1657 * Explode source_image
1658 *
1659 * This is a helper function that extracts the extension
Derek Jones4b9c6292011-07-01 17:40:48 -05001660 * from the source_image. This function lets us deal with
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001661 * source_images with multiple periods, like: my.cool.jpg
Derek Allard2067d1a2008-11-13 22:59:24 +00001662 * It returns an associative array with two elements:
Derek Jones4b9c6292011-07-01 17:40:48 -05001663 * $array['ext'] = '.jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001664 * $array['name'] = 'my.cool';
1665 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001666 * @param array
1667 * @return array
1668 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001669 public function explode_name($source_image)
Derek Allard2067d1a2008-11-13 22:59:24 +00001670 {
Derek Jones08cae632009-02-10 20:03:29 +00001671 $ext = strrchr($source_image, '.');
1672 $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
Barry Mienydd671972010-10-04 16:33:58 +02001673
Derek Jones08cae632009-02-10 20:03:29 +00001674 return array('ext' => $ext, 'name' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001675 }
1676
1677 // --------------------------------------------------------------------
1678
1679 /**
1680 * Is GD Installed?
1681 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001682 * @return bool
1683 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001684 public function gd_loaded()
Derek Allard2067d1a2008-11-13 22:59:24 +00001685 {
1686 if ( ! extension_loaded('gd'))
1687 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001688 /* As it is stated in the PHP manual, dl() is not always available
1689 * and even if so - it could generate an E_WARNING message on failure
1690 */
Andrey Andreev8e70b792012-01-12 20:19:24 +02001691 return (function_exists('dl') && @dl('gd.so'));
Derek Allard2067d1a2008-11-13 22:59:24 +00001692 }
1693
1694 return TRUE;
1695 }
1696
1697 // --------------------------------------------------------------------
1698
1699 /**
1700 * Get GD version
1701 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001702 * @return mixed
1703 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001704 public function gd_version()
Derek Allard2067d1a2008-11-13 22:59:24 +00001705 {
1706 if (function_exists('gd_info'))
1707 {
1708 $gd_version = @gd_info();
Andrey Andreev8e70b792012-01-12 20:19:24 +02001709 return preg_replace('/\D/', '', $gd_version['GD Version']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001710 }
1711
1712 return FALSE;
1713 }
1714
1715 // --------------------------------------------------------------------
1716
1717 /**
1718 * Set error message
1719 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001720 * @param string
1721 * @return void
1722 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001723 public function set_error($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +00001724 {
1725 $CI =& get_instance();
1726 $CI->lang->load('imglib');
1727
1728 if (is_array($msg))
1729 {
1730 foreach ($msg as $val)
1731 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001732 $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
Derek Allard2067d1a2008-11-13 22:59:24 +00001733 $this->error_msg[] = $msg;
1734 log_message('error', $msg);
1735 }
1736 }
1737 else
1738 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001739 $msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg);
Derek Allard2067d1a2008-11-13 22:59:24 +00001740 $this->error_msg[] = $msg;
1741 log_message('error', $msg);
1742 }
1743 }
1744
1745 // --------------------------------------------------------------------
1746
1747 /**
1748 * Show error messages
1749 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001750 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001751 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001752 * @return string
1753 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001754 public function display_errors($open = '<p>', $close = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +00001755 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001756 return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001757 }
1758
1759}
Derek Allard2067d1a2008-11-13 22:59:24 +00001760
1761/* End of file Image_lib.php */
Andrey Andreev1b815532012-04-03 16:06:03 +03001762/* Location: ./system/libraries/Image_lib.php */