blob: 9379e3ec83b3769ec2e46579c16f0d2ff0200e1f [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
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 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * Image Manipulation class
31 *
32 * @package CodeIgniter
33 * @subpackage Libraries
34 * @category Image_lib
Derek Jonesf4a4bd82011-10-20 12:18:42 -050035 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @link http://codeigniter.com/user_guide/libraries/image_lib.html
37 */
38class CI_Image_lib {
39
Timothy Warrenb8e62852012-04-26 18:40:54 -040040 /**
41 * PHP extension/library to use for image manipulation
Andrey Andreev56454792012-05-17 14:32:19 +030042 * Can be: imagemagick, netpbm, gd, gd2
Timothy Warrenb8e62852012-04-26 18:40:54 -040043 *
44 * @var string
45 */
46 public $image_library = 'gd2';
Andrey Andreev56454792012-05-17 14:32:19 +030047
Timothy Warrenb8e62852012-04-26 18:40:54 -040048 /**
49 * Path to the graphic library (if applicable)
50 *
51 * @var string
52 */
Andrey Andreev3a459572011-12-21 11:23:11 +020053 public $library_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +030054
Timothy Warrenb8e62852012-04-26 18:40:54 -040055 /**
56 * Whether to send to browser or write to disk
57 *
58 * @var bool
59 */
60 public $dynamic_output = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +030061
Timothy Warrenb8e62852012-04-26 18:40:54 -040062 /**
63 * Path to original image
64 *
65 * @var string
66 */
Andrey Andreev3a459572011-12-21 11:23:11 +020067 public $source_image = '';
Andrey Andreev56454792012-05-17 14:32:19 +030068
Timothy Warrenb8e62852012-04-26 18:40:54 -040069 /**
70 * Path to the modified image
71 *
72 * @var string
73 */
Andrey Andreev56454792012-05-17 14:32:19 +030074 public $new_image = '';
75
Timothy Warrenb8e62852012-04-26 18:40:54 -040076 /**
77 * Image width
78 *
79 * @var int
80 */
Andrey Andreev56454792012-05-17 14:32:19 +030081 public $width = '';
82
Timothy Warrenb8e62852012-04-26 18:40:54 -040083 /**
84 * Image height
85 *
86 * @var int
87 */
Andrey Andreev56454792012-05-17 14:32:19 +030088 public $height = '';
89
Timothy Warrenb8e62852012-04-26 18:40:54 -040090 /**
91 * Quality percentage of new image
92 *
93 * @var int
94 */
Andrey Andreev56454792012-05-17 14:32:19 +030095 public $quality = 90;
96
Timothy Warrenb8e62852012-04-26 18:40:54 -040097 /**
98 * Whether to create a thumbnail
99 *
100 * @var bool
101 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200102 public $create_thumb = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300103
Timothy Warrenb8e62852012-04-26 18:40:54 -0400104 /**
105 * String to add to thumbnail version of image
106 *
107 * @var string
108 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200109 public $thumb_marker = '_thumb';
Andrey Andreev56454792012-05-17 14:32:19 +0300110
Timothy Warrenb8e62852012-04-26 18:40:54 -0400111 /**
112 * Whether to maintain aspect ratio when resizing or use hard values
113 *
114 * @var bool
115 */
116 public $maintain_ratio = TRUE;
Andrey Andreev56454792012-05-17 14:32:19 +0300117
Timothy Warrenb8e62852012-04-26 18:40:54 -0400118 /**
119 * auto, height, or width. Determines what to use as the master dimension
120 *
121 * @var string
122 */
Andrey Andreev56454792012-05-17 14:32:19 +0300123 public $master_dim = 'auto';
124
Timothy Warrenb8e62852012-04-26 18:40:54 -0400125 /**
126 * Angle at to rotate image
127 *
128 * @var string
129 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200130 public $rotation_angle = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300131
Timothy Warrenb8e62852012-04-26 18:40:54 -0400132 /**
133 * X Coordinate for manipulation of the current image
134 *
135 * @var int
136 */
Andrey Andreev56454792012-05-17 14:32:19 +0300137 public $x_axis = '';
138
Timothy Warrenb8e62852012-04-26 18:40:54 -0400139 /**
140 * Y Coordinate for manipulation of the current image
141 *
142 * @var int
143 */
Andrey Andreev56454792012-05-17 14:32:19 +0300144 public $y_axis = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000145
Timothy Warrenb8e62852012-04-26 18:40:54 -0400146 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 // Watermark Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400148 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +0300149
Timothy Warrenb8e62852012-04-26 18:40:54 -0400150 /**
151 * Watermark text if graphic is not used
152 *
153 * @var string
154 */
155 public $wm_text = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300156
Timothy Warrenb8e62852012-04-26 18:40:54 -0400157 /**
158 * Type of watermarking. Options: text/overlay
159 *
160 * @var string
161 */
162 public $wm_type = 'text';
Andrey Andreev56454792012-05-17 14:32:19 +0300163
Timothy Warrenb8e62852012-04-26 18:40:54 -0400164 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400165 * Default transparency for watermark
Andrey Andreev56454792012-05-17 14:32:19 +0300166 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400167 * @var int
168 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200169 public $wm_x_transp = 4;
Andrey Andreev56454792012-05-17 14:32:19 +0300170
Timothy Warrenb8e62852012-04-26 18:40:54 -0400171 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400172 * Default transparency for watermark
173 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400174 * @var int
175 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200176 public $wm_y_transp = 4;
Andrey Andreev56454792012-05-17 14:32:19 +0300177
Timothy Warrenb8e62852012-04-26 18:40:54 -0400178 /**
179 * Watermark image path
Andrey Andreev56454792012-05-17 14:32:19 +0300180 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400181 * @var string
182 */
Andrey Andreev56454792012-05-17 14:32:19 +0300183 public $wm_overlay_path = '';
184
Timothy Warrenb8e62852012-04-26 18:40:54 -0400185 /**
186 * TT font
187 *
188 * @var string
189 */
190 public $wm_font_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300191
Timothy Warrenb8e62852012-04-26 18:40:54 -0400192 /**
193 * Font size (different versions of GD will either use points or pixels)
194 *
195 * @var int
196 */
197 public $wm_font_size = 17;
Andrey Andreev56454792012-05-17 14:32:19 +0300198
Timothy Warrenb8e62852012-04-26 18:40:54 -0400199 /**
200 * Vertical alignment: T M B
201 *
202 * @var string
203 */
204 public $wm_vrt_alignment = 'B';
Andrey Andreev56454792012-05-17 14:32:19 +0300205
Timothy Warrenb8e62852012-04-26 18:40:54 -0400206 /**
207 * Horizontal alignment: L R C
208 *
209 * @var string
210 */
211 public $wm_hor_alignment = 'C';
Andrey Andreev56454792012-05-17 14:32:19 +0300212
Timothy Warrenb8e62852012-04-26 18:40:54 -0400213 /**
214 * Padding around text
215 *
216 * @var int
217 */
218 public $wm_padding = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300219
Timothy Warrenb8e62852012-04-26 18:40:54 -0400220 /**
221 * Lets you push text to the right
222 *
223 * @var int
224 */
225 public $wm_hor_offset = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300226
Timothy Warrenb8e62852012-04-26 18:40:54 -0400227 /**
228 * Lets you push text down
229 *
230 * @var int
231 */
232 public $wm_vrt_offset = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300233
Timothy Warrenb8e62852012-04-26 18:40:54 -0400234 /**
235 * Text color
236 *
237 * @var string
238 */
Andrey Andreev56454792012-05-17 14:32:19 +0300239 protected $wm_font_color = '#ffffff';
240
Timothy Warrenb8e62852012-04-26 18:40:54 -0400241 /**
242 * Dropshadow color
243 *
244 * @var string
245 */
Andrey Andreev56454792012-05-17 14:32:19 +0300246 protected $wm_shadow_color = '';
247
Timothy Warrenb8e62852012-04-26 18:40:54 -0400248 /**
249 * Dropshadow distance
250 *
251 * @var int
252 */
253 public $wm_shadow_distance = 2;
Andrey Andreev56454792012-05-17 14:32:19 +0300254
Timothy Warrenb8e62852012-04-26 18:40:54 -0400255 /**
256 * Image opacity: 1 - 100 Only works with image
257 *
258 * @var int
259 */
Andrey Andreev56454792012-05-17 14:32:19 +0300260 public $wm_opacity = 50;
Derek Allard2067d1a2008-11-13 22:59:24 +0000261
Timothy Warrenb8e62852012-04-26 18:40:54 -0400262 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000263 // Private Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400264 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +0300265
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400266 /**
267 * Source image folder
268 *
269 * @var string
270 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200271 public $source_folder = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300272
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400273 /**
274 * Destination image folder
275 *
276 * @var string
277 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200278 public $dest_folder = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300279
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400280 /**
281 * Image mime-type
282 *
283 * @var string
284 */
Andrey Andreev56454792012-05-17 14:32:19 +0300285 public $mime_type = '';
286
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400287 /**
Andrey Andreev56454792012-05-17 14:32:19 +0300288 * Original image width
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400289 *
290 * @var int
291 */
Andrey Andreev56454792012-05-17 14:32:19 +0300292 public $orig_width = '';
293
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400294 /**
295 * Original image height
296 *
297 * @var int
298 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200299 public $orig_height = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300300
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400301 /**
302 * Image format
Andrey Andreev56454792012-05-17 14:32:19 +0300303 *
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400304 * @var string
305 */
Andrey Andreev56454792012-05-17 14:32:19 +0300306 public $image_type = '';
307
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400308 /**
309 * Size of current image
310 *
311 * @var string
312 */
Andrey Andreev56454792012-05-17 14:32:19 +0300313 public $size_str = '';
314
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400315 /**
316 * Full path to source image
317 *
318 * @var string
319 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200320 public $full_src_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300321
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400322 /**
323 * Full path to destination image
324 *
325 * @var string
326 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200327 public $full_dst_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300328
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400329 /**
330 * Name of function to create image
331 *
332 * @var string
333 */
Andrey Andreev56454792012-05-17 14:32:19 +0300334 public $create_fnc = 'imagecreatetruecolor';
335
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400336 /**
337 * Name of function to copy image
338 *
339 * @var string
340 */
Andrey Andreev56454792012-05-17 14:32:19 +0300341 public $copy_fnc = 'imagecopyresampled';
342
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400343 /**
344 * Error messages
345 *
346 * @var array
347 */
Andrey Andreev56454792012-05-17 14:32:19 +0300348 public $error_msg = array();
349
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400350 /**
351 * Whether to have a drop shadow on watermark
352 *
353 * @var bool
354 */
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200355 protected $wm_use_drop_shadow = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300356
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400357 /**
358 * Whether to use truetype fonts
359 *
360 * @var bool
361 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200362 public $wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000363
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400364 /**
365 * Initialize Image Library
366 *
367 * @param array $props
Andrey Andreev56454792012-05-17 14:32:19 +0300368 * @return void
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400369 */
Greg Akera9263282010-11-10 15:26:43 -0600370 public function __construct($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000371 {
372 if (count($props) > 0)
373 {
374 $this->initialize($props);
375 }
376
Andrey Andreev8e70b792012-01-12 20:19:24 +0200377 log_message('debug', 'Image Lib Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000378 }
379
380 // --------------------------------------------------------------------
381
382 /**
383 * Initialize image properties
384 *
385 * Resets values in case this class is used in a loop
386 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 * @return void
388 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200389 public function clear()
Derek Allard2067d1a2008-11-13 22:59:24 +0000390 {
Michael Denniscb07a322011-08-20 23:40:59 -0700391 $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 +0000392
393 foreach ($props as $val)
394 {
395 $this->$val = '';
396 }
397
Michael Denniscb07a322011-08-20 23:40:59 -0700398 $this->image_library = 'gd2';
399 $this->dynamic_output = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300400 $this->quality = 90;
Michael Denniscb07a322011-08-20 23:40:59 -0700401 $this->create_thumb = FALSE;
402 $this->thumb_marker = '_thumb';
403 $this->maintain_ratio = TRUE;
404 $this->master_dim = 'auto';
405 $this->wm_type = 'text';
406 $this->wm_x_transp = 4;
407 $this->wm_y_transp = 4;
408 $this->wm_font_size = 17;
409 $this->wm_vrt_alignment = 'B';
410 $this->wm_hor_alignment = 'C';
411 $this->wm_padding = 0;
412 $this->wm_hor_offset = 0;
413 $this->wm_vrt_offset = 0;
414 $this->wm_font_color = '#ffffff';
415 $this->wm_shadow_distance = 2;
416 $this->wm_opacity = 50;
417 $this->create_fnc = 'imagecreatetruecolor';
418 $this->copy_fnc = 'imagecopyresampled';
419 $this->error_msg = array();
420 $this->wm_use_drop_shadow = FALSE;
421 $this->wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 }
423
424 // --------------------------------------------------------------------
425
426 /**
427 * initialize image preferences
428 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000429 * @param array
430 * @return bool
431 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200432 public function initialize($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000433 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200434 // Convert array elements into class variables
Derek Allard2067d1a2008-11-13 22:59:24 +0000435 if (count($props) > 0)
436 {
437 foreach ($props as $key => $val)
438 {
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200439 if (property_exists($this, $key))
440 {
441 if (in_array($key, array('wm_font_color', 'wm_shadow_color')))
442 {
Andrey Andreev8323ae62011-12-31 18:39:10 +0200443 if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200444 {
Andrey Andreevcf2ba9e2012-01-01 21:57:13 +0200445 /* $matches[1] contains our hex color value, but it might be
Andrey Andreev8323ae62011-12-31 18:39:10 +0200446 * both in the full 6-length format or the shortened 3-length
447 * value.
Andrey Andreevbb96c8b2011-12-31 18:48:39 +0200448 * We'll later need the full version, so we keep it if it's
Andrey Andreev8323ae62011-12-31 18:39:10 +0200449 * already there and if not - we'll convert to it. We can
450 * access string characters by their index as in an array,
451 * so we'll do that and use concatenation to form the final
452 * value:
453 */
Andrey Andreev665af0c2011-12-30 14:39:29 +0200454 $val = (strlen($matches[1]) === 6)
455 ? '#'.$matches[1]
456 : '#'.$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 +0200457 }
458 else
459 {
460 continue;
461 }
462 }
463
464 $this->$key = $val;
465 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 }
467 }
468
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200469 // Is there a source image? If not, there's no reason to continue
Alex Bilbied261b1e2012-06-02 11:12:16 +0100470 if ($this->source_image === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000471 {
472 $this->set_error('imglib_source_image_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500473 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 }
475
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200476 /* Is getimagesize() available?
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 *
478 * We use it to determine the image properties (width/height).
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200479 * Note: We need to figure out how to determine image
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 * properties using ImageMagick and NetPBM
Derek Allard2067d1a2008-11-13 22:59:24 +0000481 */
482 if ( ! function_exists('getimagesize'))
483 {
484 $this->set_error('imglib_gd_required_for_props');
485 return FALSE;
486 }
487
488 $this->image_library = strtolower($this->image_library);
489
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200490 /* Set the full server path
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 *
492 * The source image may or may not contain a path.
493 * Either way, we'll try use realpath to generate the
494 * full server path in order to more reliably read it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200496 if (function_exists('realpath') && @realpath($this->source_image) !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200498 $full_source_path = str_replace('\\', '/', realpath($this->source_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000499 }
500 else
501 {
502 $full_source_path = $this->source_image;
503 }
504
505 $x = explode('/', $full_source_path);
506 $this->source_image = end($x);
507 $this->source_folder = str_replace($this->source_image, '', $full_source_path);
508
509 // Set the Image Properties
510 if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
511 {
Eric Barnesb1673362011-12-05 22:05:38 -0500512 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000513 }
514
515 /*
516 * Assign the "new" image name/path
517 *
518 * If the user has set a "new_image" name it means
519 * we are making a copy of the source image. If not
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200520 * it means we are altering the original. We'll
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 * set the destination filename and path accordingly.
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100523 if ($this->new_image === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000524 {
525 $this->dest_image = $this->source_image;
526 $this->dest_folder = $this->source_folder;
527 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200528 elseif (strpos($this->new_image, '/') === FALSE)
529 {
530 $this->dest_folder = $this->source_folder;
531 $this->dest_image = $this->new_image;
532 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000533 else
534 {
Andrey Andreev1b815532012-04-03 16:06:03 +0300535 if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000536 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200537 $full_dest_path = str_replace('\\', '/', realpath($this->new_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 }
539 else
540 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200541 $full_dest_path = $this->new_image;
542 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000543
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200544 // Is there a file name?
545 if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path))
546 {
547 $this->dest_folder = $full_dest_path.'/';
548 $this->dest_image = $this->source_image;
549 }
550 else
551 {
552 $x = explode('/', $full_dest_path);
553 $this->dest_image = end($x);
554 $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 }
556 }
557
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200558 /* Compile the finalized filenames/paths
Derek Allard2067d1a2008-11-13 22:59:24 +0000559 *
560 * We'll create two master strings containing the
561 * full server path to the source image and the
562 * full server path to the destination image.
563 * We'll also split the destination image name
564 * so we can insert the thumbnail marker if needed.
Derek Allard2067d1a2008-11-13 22:59:24 +0000565 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100566 if ($this->create_thumb === FALSE OR $this->thumb_marker === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 {
568 $this->thumb_marker = '';
569 }
570
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200571 $xp = $this->explode_name($this->dest_image);
Derek Allard2067d1a2008-11-13 22:59:24 +0000572
573 $filename = $xp['name'];
574 $file_ext = $xp['ext'];
575
576 $this->full_src_path = $this->source_folder.$this->source_image;
577 $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
578
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200579 /* Should we maintain image proportions?
Derek Allard2067d1a2008-11-13 22:59:24 +0000580 *
581 * When creating thumbs or copies, the target width/height
582 * might not be in correct proportion with the source
Andrey Andreev8e70b792012-01-12 20:19:24 +0200583 * image's width/height. We'll recalculate it here.
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100585 if ($this->maintain_ratio === TRUE && ($this->width !== 0 OR $this->height !== 0))
Derek Allard2067d1a2008-11-13 22:59:24 +0000586 {
587 $this->image_reproportion();
588 }
589
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200590 /* Was a width and height specified?
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 *
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200592 * If the destination width/height was not submitted we
593 * will use the values from the actual file
Derek Allard2067d1a2008-11-13 22:59:24 +0000594 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100595 if ($this->width === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200596 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000597 $this->width = $this->orig_width;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200598 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000599
Alex Bilbied261b1e2012-06-02 11:12:16 +0100600 if ($this->height === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200601 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000602 $this->height = $this->orig_height;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200603 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000604
605 // Set the quality
Andrey Andreev8e70b792012-01-12 20:19:24 +0200606 $this->quality = trim(str_replace('%', '', $this->quality));
Derek Allard2067d1a2008-11-13 22:59:24 +0000607
Alex Bilbied261b1e2012-06-02 11:12:16 +0100608 if ($this->quality === '' OR $this->quality === 0 OR ! preg_match('/^[0-9]+$/', $this->quality))
Andrey Andreev8e70b792012-01-12 20:19:24 +0200609 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000610 $this->quality = 90;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200611 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000612
613 // Set the x/y coordinates
Andrey Andreev5036c9c2012-06-04 15:34:56 +0300614 is_numeric($this->x_axis) OR $this->x_axis = 0;
615 is_numeric($this->y_axis) OR $this->y_axis = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +0000616
617 // Watermark-related Stuff...
Alex Bilbied261b1e2012-06-02 11:12:16 +0100618 if ($this->wm_overlay_path !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000619 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200620 $this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
Derek Allard2067d1a2008-11-13 22:59:24 +0000621 }
622
Alex Bilbied261b1e2012-06-02 11:12:16 +0100623 if ($this->wm_shadow_color !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 {
625 $this->wm_use_drop_shadow = TRUE;
626 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100627 elseif ($this->wm_use_drop_shadow === TRUE && $this->wm_shadow_color === '')
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200628 {
629 $this->wm_use_drop_shadow = FALSE;
630 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000631
Alex Bilbied261b1e2012-06-02 11:12:16 +0100632 if ($this->wm_font_path !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000633 {
634 $this->wm_use_truetype = TRUE;
635 }
636
637 return TRUE;
638 }
639
640 // --------------------------------------------------------------------
641
642 /**
643 * Image Resize
644 *
645 * This is a wrapper function that chooses the proper
646 * resize function based on the protocol specified
647 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000648 * @return bool
649 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200650 public function resize()
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 {
Andrey Andreev1a9f52c2012-01-07 01:06:34 +0200652 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000653 return $this->$protocol('resize');
654 }
655
656 // --------------------------------------------------------------------
657
658 /**
659 * Image Crop
660 *
661 * This is a wrapper function that chooses the proper
662 * cropping function based on the protocol specified
663 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000664 * @return bool
665 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200666 public function crop()
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 {
Andrey Andreev5a67e3d2012-01-07 01:21:09 +0200668 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000669 return $this->$protocol('crop');
670 }
671
672 // --------------------------------------------------------------------
673
674 /**
675 * Image Rotate
676 *
677 * This is a wrapper function that chooses the proper
678 * rotation function based on the protocol specified
679 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000680 * @return bool
681 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200682 public function rotate()
Derek Allard2067d1a2008-11-13 22:59:24 +0000683 {
684 // Allowed rotation values
685 $degs = array(90, 180, 270, 'vrt', 'hor');
686
Alex Bilbied261b1e2012-06-02 11:12:16 +0100687 if ($this->rotation_angle === '' OR ! in_array($this->rotation_angle, $degs))
Derek Allard2067d1a2008-11-13 22:59:24 +0000688 {
689 $this->set_error('imglib_rotation_angle_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500690 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000691 }
692
693 // Reassign the width and height
Alex Bilbied261b1e2012-06-02 11:12:16 +0100694 if ($this->rotation_angle === 90 OR $this->rotation_angle === 270)
Derek Allard2067d1a2008-11-13 22:59:24 +0000695 {
696 $this->width = $this->orig_height;
697 $this->height = $this->orig_width;
698 }
699 else
700 {
701 $this->width = $this->orig_width;
702 $this->height = $this->orig_height;
703 }
704
Derek Allard2067d1a2008-11-13 22:59:24 +0000705 // Choose resizing function
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200706 if ($this->image_library === 'imagemagick' OR $this->image_library === 'netpbm')
Derek Allard2067d1a2008-11-13 22:59:24 +0000707 {
708 $protocol = 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000709 return $this->$protocol('rotate');
710 }
711
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200712 return ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
713 ? $this->image_mirror_gd()
714 : $this->image_rotate_gd();
Derek Allard2067d1a2008-11-13 22:59:24 +0000715 }
716
717 // --------------------------------------------------------------------
718
719 /**
720 * Image Process Using GD/GD2
721 *
722 * This function will resize or crop
723 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000724 * @param string
725 * @return bool
726 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200727 public function image_process_gd($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000728 {
729 $v2_override = FALSE;
730
731 // If the target width/height match the source, AND if the new file name is not equal to the old file name
732 // 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 +0100733 if ($this->dynamic_output === FALSE && $this->orig_width === $this->width && $this->orig_height === $this->height)
Derek Allard2067d1a2008-11-13 22:59:24 +0000734 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100735 if ($this->source_image !== $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000736 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200737 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000738 }
Andrey Andreeva92b9032011-12-24 19:05:58 +0200739
740 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000741 }
742
743 // Let's set up our values based on the action
Alex Bilbied261b1e2012-06-02 11:12:16 +0100744 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000745 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200746 // Reassign the source width/height if cropping
Derek Jones4b9c6292011-07-01 17:40:48 -0500747 $this->orig_width = $this->width;
Derek Allard2067d1a2008-11-13 22:59:24 +0000748 $this->orig_height = $this->height;
749
750 // GD 2.0 has a cropping bug so we'll test for it
751 if ($this->gd_version() !== FALSE)
752 {
753 $gd_version = str_replace('0', '', $this->gd_version());
Andrey Andreev5036c9c2012-06-04 15:34:56 +0300754 $v2_override = ($gd_version === 2);
Derek Allard2067d1a2008-11-13 22:59:24 +0000755 }
756 }
757 else
758 {
759 // If resizing the x/y axis must be zero
760 $this->x_axis = 0;
761 $this->y_axis = 0;
762 }
763
Derek Jones4b9c6292011-07-01 17:40:48 -0500764 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000765 if ( ! ($src_img = $this->image_create_gd()))
766 {
767 return FALSE;
768 }
769
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200770 /* Create the image
771 *
772 * Old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
773 * it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
774 * below should that ever prove inaccurate.
775 *
Alex Bilbied261b1e2012-06-02 11:12:16 +0100776 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override === FALSE)
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200777 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200778 if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000779 {
780 $create = 'imagecreatetruecolor';
781 $copy = 'imagecopyresampled';
782 }
783 else
784 {
785 $create = 'imagecreate';
786 $copy = 'imagecopyresized';
787 }
788
789 $dst_img = $create($this->width, $this->height);
Derek Jones595bfd12010-08-20 10:28:22 -0500790
Alex Bilbied261b1e2012-06-02 11:12:16 +0100791 if ($this->image_type === 3) // png we can actually preserve transparency
Derek Jones595bfd12010-08-20 10:28:22 -0500792 {
793 imagealphablending($dst_img, FALSE);
794 imagesavealpha($dst_img, TRUE);
795 }
Barry Mienydd671972010-10-04 16:33:58 +0200796
Derek Allard2067d1a2008-11-13 22:59:24 +0000797 $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
798
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200799 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +0100800 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000801 {
802 $this->image_display_gd($dst_img);
803 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200804 elseif ( ! $this->image_save_gd($dst_img)) // Or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000805 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200806 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000807 }
808
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200809 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000810 imagedestroy($dst_img);
811 imagedestroy($src_img);
812
813 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000814 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000815
816 return TRUE;
817 }
818
819 // --------------------------------------------------------------------
820
821 /**
822 * Image Process Using ImageMagick
823 *
824 * This function will resize, crop or rotate
825 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000826 * @param string
827 * @return bool
828 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200829 public function image_process_imagemagick($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000830 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500831 // Do we have a vaild library path?
Alex Bilbied261b1e2012-06-02 11:12:16 +0100832 if ($this->library_path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000833 {
834 $this->set_error('imglib_libpath_invalid');
835 return FALSE;
836 }
837
Andrey Andreev8e70b792012-01-12 20:19:24 +0200838 if ( ! preg_match('/convert$/i', $this->library_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000839 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200840 $this->library_path = rtrim($this->library_path, '/').'/convert';
Derek Allard2067d1a2008-11-13 22:59:24 +0000841 }
842
843 // Execute the command
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200844 $cmd = $this->library_path.' -quality '.$this->quality;
Derek Allard2067d1a2008-11-13 22:59:24 +0000845
Alex Bilbied261b1e2012-06-02 11:12:16 +0100846 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000847 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200848 $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 +0000849 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100850 elseif ($action === 'rotate')
Derek Allard2067d1a2008-11-13 22:59:24 +0000851 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200852 $angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
853 ? '-flop' : '-rotate '.$this->rotation_angle;
Derek Allard2067d1a2008-11-13 22:59:24 +0000854
Andrey Andreev8e70b792012-01-12 20:19:24 +0200855 $cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000856 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200857 else // Resize
Derek Allard2067d1a2008-11-13 22:59:24 +0000858 {
Omar24063af2012-07-02 13:50:17 -0300859 if($this->maintain_ratio === TRUE)
860 {
861 $cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
862 }
Omarbb531d62012-06-29 10:48:28 -0300863 else
Omar24063af2012-07-02 13:50:17 -0300864 {
865 $cmd .= ' -resize '.$this->width.'x'.$this->height.'\! "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
866 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000867 }
868
869 $retval = 1;
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200870 // exec() might be disabled
871 if (function_usable('exec'))
872 {
873 @exec($cmd, $output, $retval);
874 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000875
Andrey Andreev8e70b792012-01-12 20:19:24 +0200876 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000877 if ($retval > 0)
878 {
879 $this->set_error('imglib_image_process_failed');
880 return FALSE;
881 }
882
883 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000884 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000885
886 return TRUE;
887 }
888
889 // --------------------------------------------------------------------
890
891 /**
892 * Image Process Using NetPBM
893 *
894 * This function will resize, crop or rotate
895 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000896 * @param string
897 * @return bool
898 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200899 public function image_process_netpbm($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000900 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100901 if ($this->library_path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000902 {
903 $this->set_error('imglib_libpath_invalid');
904 return FALSE;
905 }
906
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200907 // Build the resizing command
Derek Allard2067d1a2008-11-13 22:59:24 +0000908 switch ($this->image_type)
909 {
910 case 1 :
Andrey Andreev56454792012-05-17 14:32:19 +0300911 $cmd_in = 'giftopnm';
912 $cmd_out = 'ppmtogif';
Derek Allard2067d1a2008-11-13 22:59:24 +0000913 break;
914 case 2 :
Andrey Andreev56454792012-05-17 14:32:19 +0300915 $cmd_in = 'jpegtopnm';
916 $cmd_out = 'ppmtojpeg';
Derek Allard2067d1a2008-11-13 22:59:24 +0000917 break;
918 case 3 :
Andrey Andreev56454792012-05-17 14:32:19 +0300919 $cmd_in = 'pngtopnm';
920 $cmd_out = 'ppmtopng';
Derek Allard2067d1a2008-11-13 22:59:24 +0000921 break;
922 }
923
Alex Bilbied261b1e2012-06-02 11:12:16 +0100924 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000925 {
926 $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
927 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100928 elseif ($action === 'rotate')
Derek Allard2067d1a2008-11-13 22:59:24 +0000929 {
930 switch ($this->rotation_angle)
931 {
Andrey Andreev56454792012-05-17 14:32:19 +0300932 case 90: $angle = 'r270';
Derek Allard2067d1a2008-11-13 22:59:24 +0000933 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300934 case 180: $angle = 'r180';
Derek Allard2067d1a2008-11-13 22:59:24 +0000935 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300936 case 270: $angle = 'r90';
Derek Allard2067d1a2008-11-13 22:59:24 +0000937 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300938 case 'vrt': $angle = 'tb';
Derek Allard2067d1a2008-11-13 22:59:24 +0000939 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300940 case 'hor': $angle = 'lr';
Derek Allard2067d1a2008-11-13 22:59:24 +0000941 break;
942 }
943
944 $cmd_inner = 'pnmflip -'.$angle.' ';
945 }
946 else // Resize
947 {
948 $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
949 }
950
951 $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
952
953 $retval = 1;
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200954 // exec() might be disabled
955 if (function_usable('exec'))
956 {
957 @exec($cmd, $output, $retval);
958 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000959
Andrey Andreev8e70b792012-01-12 20:19:24 +0200960 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000961 if ($retval > 0)
962 {
963 $this->set_error('imglib_image_process_failed');
964 return FALSE;
965 }
966
967 // With NetPBM we have to create a temporary image.
968 // If you try manipulating the original it fails so
969 // we have to rename the temp file.
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200970 copy($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200971 unlink($this->dest_folder.'netpbm.tmp');
Derek Jones172e1612009-10-13 14:32:48 +0000972 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000973
974 return TRUE;
975 }
976
977 // --------------------------------------------------------------------
978
979 /**
980 * Image Rotate Using GD
981 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000982 * @return bool
983 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200984 public function image_rotate_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +0000985 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200986 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000987 if ( ! ($src_img = $this->image_create_gd()))
988 {
989 return FALSE;
990 }
991
992 // Set the background color
993 // This won't work with transparent PNG files so we are
994 // going to have to figure out how to determine the color
995 // of the alpha channel in a future release.
996
997 $white = imagecolorallocate($src_img, 255, 255, 255);
998
Andrey Andreev8e70b792012-01-12 20:19:24 +0200999 // Rotate it!
Derek Allard2067d1a2008-11-13 22:59:24 +00001000 $dst_img = imagerotate($src_img, $this->rotation_angle, $white);
1001
Andrey Andreev8e70b792012-01-12 20:19:24 +02001002 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001003 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001004 {
1005 $this->image_display_gd($dst_img);
1006 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001007 elseif ( ! $this->image_save_gd($dst_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001008 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001009 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001010 }
1011
Andrey Andreev8e70b792012-01-12 20:19:24 +02001012 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001013 imagedestroy($dst_img);
1014 imagedestroy($src_img);
1015
1016 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +00001017 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001018
Pascal Kriete8761ef52011-02-14 13:13:52 -05001019 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001020 }
1021
1022 // --------------------------------------------------------------------
1023
1024 /**
1025 * Create Mirror Image using GD
1026 *
1027 * This function will flip horizontal or vertical
1028 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001029 * @return bool
1030 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001031 public function image_mirror_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +00001032 {
1033 if ( ! $src_img = $this->image_create_gd())
1034 {
1035 return FALSE;
1036 }
1037
Derek Jones4b9c6292011-07-01 17:40:48 -05001038 $width = $this->orig_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001039 $height = $this->orig_height;
1040
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001041 if ($this->rotation_angle === 'hor')
Derek Allard2067d1a2008-11-13 22:59:24 +00001042 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001043 for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001044 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001045 while ($left < $right)
1046 {
1047 $cl = imagecolorat($src_img, $left, $i);
1048 $cr = imagecolorat($src_img, $right, $i);
1049
1050 imagesetpixel($src_img, $left, $i, $cr);
1051 imagesetpixel($src_img, $right, $i, $cl);
1052
1053 $left++;
1054 $right--;
1055 }
1056 }
1057 }
1058 else
1059 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001060 for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001061 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001062 while ($top < $bot)
1063 {
1064 $ct = imagecolorat($src_img, $i, $top);
1065 $cb = imagecolorat($src_img, $i, $bot);
1066
1067 imagesetpixel($src_img, $i, $top, $cb);
1068 imagesetpixel($src_img, $i, $bot, $ct);
1069
1070 $top++;
1071 $bot--;
1072 }
1073 }
1074 }
1075
Andrey Andreev8e70b792012-01-12 20:19:24 +02001076 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001077 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001078 {
1079 $this->image_display_gd($src_img);
1080 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001081 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001082 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001083 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001084 }
1085
Andrey Andreev8e70b792012-01-12 20:19:24 +02001086 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001087 imagedestroy($src_img);
1088
1089 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +00001090 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001091
1092 return TRUE;
1093 }
1094
1095 // --------------------------------------------------------------------
1096
1097 /**
1098 * Image Watermark
1099 *
1100 * This is a wrapper function that chooses the type
1101 * of watermarking based on the specified preference.
1102 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001103 * @return bool
1104 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001105 public function watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001106 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001107 return ($this->wm_type === 'overlay') ? $this->overlay_watermark() : $this->text_watermark();
Derek Allard2067d1a2008-11-13 22:59:24 +00001108 }
1109
1110 // --------------------------------------------------------------------
1111
1112 /**
1113 * Watermark - Graphic Version
1114 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001115 * @return bool
1116 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001117 public function overlay_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001118 {
1119 if ( ! function_exists('imagecolortransparent'))
1120 {
1121 $this->set_error('imglib_gd_required');
1122 return FALSE;
1123 }
1124
Andrey Andreev8e70b792012-01-12 20:19:24 +02001125 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001126 $this->get_image_properties();
1127
Andrey Andreev8e70b792012-01-12 20:19:24 +02001128 // Fetch watermark image properties
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001129 $props = $this->get_image_properties($this->wm_overlay_path, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001130 $wm_img_type = $props['image_type'];
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001131 $wm_width = $props['width'];
1132 $wm_height = $props['height'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001133
Andrey Andreev8e70b792012-01-12 20:19:24 +02001134 // Create two image resources
Derek Jones4b9c6292011-07-01 17:40:48 -05001135 $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001136 $src_img = $this->image_create_gd($this->full_src_path);
1137
1138 // Reverse the offset if necessary
1139 // When the image is positioned at the bottom
1140 // we don't want the vertical offset to push it
Andrey Andreev8e70b792012-01-12 20:19:24 +02001141 // further down. We want the reverse, so we'll
1142 // invert the offset. Same with the horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001143 // offset when the image is at the right
1144
Andrey Andreev8e70b792012-01-12 20:19:24 +02001145 $this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
1146 $this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001147
Alex Bilbied261b1e2012-06-02 11:12:16 +01001148 if ($this->wm_vrt_alignment === 'B')
Derek Allard2067d1a2008-11-13 22:59:24 +00001149 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1150
Alex Bilbied261b1e2012-06-02 11:12:16 +01001151 if ($this->wm_hor_alignment === 'R')
Derek Allard2067d1a2008-11-13 22:59:24 +00001152 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1153
Andrey Andreev8e70b792012-01-12 20:19:24 +02001154 // Set the base x and y axis values
Derek Allard2067d1a2008-11-13 22:59:24 +00001155 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1156 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1157
Andrey Andreev8e70b792012-01-12 20:19:24 +02001158 // Set the vertical position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001159 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001160 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001161 $y_axis += ($this->orig_height / 2) - ($wm_height / 2);
1162 }
1163 elseif ($this->wm_vrt_alignment === 'B')
1164 {
1165 $y_axis += $this->orig_height - $wm_height;
Derek Allard2067d1a2008-11-13 22:59:24 +00001166 }
1167
Andrey Andreev8e70b792012-01-12 20:19:24 +02001168 // Set the horizontal position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001169 if ($this->wm_hor_alignment === 'C')
Derek Allard2067d1a2008-11-13 22:59:24 +00001170 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001171 $x_axis += ($this->orig_width / 2) - ($wm_width / 2);
1172 }
1173 elseif ($this->wm_hor_alignment === 'R')
1174 {
1175 $x_axis += $this->orig_width - $wm_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001176 }
1177
Derek Jones4b9c6292011-07-01 17:40:48 -05001178 // Build the finalized image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001179 if ($wm_img_type === 3 && function_exists('imagealphablending'))
Derek Allard2067d1a2008-11-13 22:59:24 +00001180 {
1181 @imagealphablending($src_img, TRUE);
Barry Mienydd671972010-10-04 16:33:58 +02001182 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001183
1184 // Set RGB values for text and shadow
1185 $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
1186 $alpha = ($rgba & 0x7F000000) >> 24;
1187
1188 // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1189 if ($alpha > 0)
1190 {
1191 // copy the image directly, the image's alpha transparency being the sole determinant of blending
1192 imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
1193 }
1194 else
1195 {
1196 // set our RGB value from above to be transparent and merge the images with the specified opacity
1197 imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
1198 imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
1199 }
1200
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001201 // Output the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001202 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001203 {
1204 $this->image_display_gd($src_img);
1205 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001206 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001207 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001208 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001209 }
1210
1211 imagedestroy($src_img);
1212 imagedestroy($wm_img);
1213
1214 return TRUE;
1215 }
1216
1217 // --------------------------------------------------------------------
1218
1219 /**
1220 * Watermark - Text Version
1221 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001222 * @return bool
1223 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001224 public function text_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001225 {
1226 if ( ! ($src_img = $this->image_create_gd()))
1227 {
1228 return FALSE;
1229 }
1230
Alex Bilbied261b1e2012-06-02 11:12:16 +01001231 if ($this->wm_use_truetype === TRUE && ! file_exists($this->wm_font_path))
Derek Allard2067d1a2008-11-13 22:59:24 +00001232 {
1233 $this->set_error('imglib_missing_font');
1234 return FALSE;
1235 }
1236
Andrey Andreev8e70b792012-01-12 20:19:24 +02001237 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001238 $this->get_image_properties();
1239
Derek Allard2067d1a2008-11-13 22:59:24 +00001240 // Reverse the vertical offset
1241 // When the image is positioned at the bottom
1242 // we don't want the vertical offset to push it
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001243 // further down. We want the reverse, so we'll
Andrey Andreev8e70b792012-01-12 20:19:24 +02001244 // invert the offset. Note: The horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001245 // offset flips itself automatically
1246
Alex Bilbied261b1e2012-06-02 11:12:16 +01001247 if ($this->wm_vrt_alignment === 'B')
Derek Allard2067d1a2008-11-13 22:59:24 +00001248 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1249
Alex Bilbied261b1e2012-06-02 11:12:16 +01001250 if ($this->wm_hor_alignment === 'R')
Derek Allard2067d1a2008-11-13 22:59:24 +00001251 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1252
1253 // Set font width and height
1254 // These are calculated differently depending on
1255 // whether we are using the true type font or not
Alex Bilbied261b1e2012-06-02 11:12:16 +01001256 if ($this->wm_use_truetype === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001257 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001258 if ($this->wm_font_size === '')
Andrey Andreeva92b9032011-12-24 19:05:58 +02001259 {
1260 $this->wm_font_size = 17;
1261 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001262
Derek Jones4b9c6292011-07-01 17:40:48 -05001263 $fontwidth = $this->wm_font_size-($this->wm_font_size/4);
Derek Allard2067d1a2008-11-13 22:59:24 +00001264 $fontheight = $this->wm_font_size;
1265 $this->wm_vrt_offset += $this->wm_font_size;
1266 }
1267 else
1268 {
Derek Jones4b9c6292011-07-01 17:40:48 -05001269 $fontwidth = imagefontwidth($this->wm_font_size);
Derek Allard2067d1a2008-11-13 22:59:24 +00001270 $fontheight = imagefontheight($this->wm_font_size);
1271 }
1272
1273 // Set base X and Y axis values
1274 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1275 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1276
Alex Bilbied261b1e2012-06-02 11:12:16 +01001277 if ($this->wm_use_drop_shadow === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001278 $this->wm_shadow_distance = 0;
1279
1280 $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
1281 $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
1282
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001283 // Set verticle alignment
1284 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001285 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001286 $y_axis += ($this->orig_height / 2) + ($fontheight / 2);
1287 }
1288 elseif ($this->wm_vrt_alignment === 'B')
1289 {
1290 $y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2);
Derek Allard2067d1a2008-11-13 22:59:24 +00001291 }
1292
1293 $x_shad = $x_axis + $this->wm_shadow_distance;
1294 $y_shad = $y_axis + $this->wm_shadow_distance;
1295
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001296 if ($this->wm_use_drop_shadow)
Derek Allard2067d1a2008-11-13 22:59:24 +00001297 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001298 // Set horizontal alignment
1299 if ($this->wm_hor_alignment === 'R')
1300 {
1301 $x_shad += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1302 $x_axis += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1303 }
1304 elseif ($this->wm_hor_alignment === 'C')
1305 {
1306 $x_shad += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1307 $x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1308 }
1309
Andrey Andreev8323ae62011-12-31 18:39:10 +02001310 /* Set RGB values for text and shadow
1311 *
1312 * First character is #, so we don't really need it.
1313 * Get the rest of the string and split it into 2-length
1314 * hex values:
1315 */
1316 $txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001317 $txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
Andrey Andreev8323ae62011-12-31 18:39:10 +02001318 $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
Ronald Beilsma8f80bc42012-01-12 16:41:49 +01001319 $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001320
Andrey Andreev8e70b792012-01-12 20:19:24 +02001321 // Add the text to the source image
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001322 if ($this->wm_use_truetype)
1323 {
1324 imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
1325 imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
1326 }
1327 else
1328 {
1329 imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
1330 imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
1331 }
Andrey Andreev99ae2262012-10-05 15:14:30 +03001332
1333 // We can preserve transparency for PNG images
1334 if ($this->image_type === 3)
1335 {
1336 imagealphablending($src_img, FALSE);
1337 imagesavealpha($src_img, TRUE);
1338 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001339 }
1340
Andrey Andreev8e70b792012-01-12 20:19:24 +02001341 // Output the final image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001342 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001343 {
1344 $this->image_display_gd($src_img);
1345 }
1346 else
1347 {
1348 $this->image_save_gd($src_img);
1349 }
1350
1351 imagedestroy($src_img);
1352
1353 return TRUE;
1354 }
1355
1356 // --------------------------------------------------------------------
1357
1358 /**
1359 * Create Image - GD
1360 *
1361 * This simply creates an image resource handle
1362 * based on the type of image being processed
1363 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001364 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001365 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001366 * @return resource
1367 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001368 public function image_create_gd($path = '', $image_type = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001369 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001370 if ($path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001371 $path = $this->full_src_path;
1372
Alex Bilbied261b1e2012-06-02 11:12:16 +01001373 if ($image_type === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001374 $image_type = $this->image_type;
1375
1376
1377 switch ($image_type)
1378 {
1379 case 1 :
1380 if ( ! function_exists('imagecreatefromgif'))
1381 {
1382 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1383 return FALSE;
1384 }
1385
1386 return imagecreatefromgif($path);
1387 break;
1388 case 2 :
1389 if ( ! function_exists('imagecreatefromjpeg'))
1390 {
1391 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1392 return FALSE;
1393 }
1394
1395 return imagecreatefromjpeg($path);
1396 break;
1397 case 3 :
1398 if ( ! function_exists('imagecreatefrompng'))
1399 {
1400 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1401 return FALSE;
1402 }
1403
1404 return imagecreatefrompng($path);
1405 break;
1406
1407 }
1408
1409 $this->set_error(array('imglib_unsupported_imagecreate'));
1410 return FALSE;
1411 }
1412
1413 // --------------------------------------------------------------------
1414
1415 /**
1416 * Write image file to disk - GD
1417 *
1418 * Takes an image resource as input and writes the file
1419 * to the specified destination
1420 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001421 * @param resource
1422 * @return bool
1423 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001424 public function image_save_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001425 {
1426 switch ($this->image_type)
1427 {
Andrey Andreev56454792012-05-17 14:32:19 +03001428 case 1:
1429 if ( ! function_exists('imagegif'))
1430 {
1431 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1432 return FALSE;
1433 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001434
Andrey Andreev56454792012-05-17 14:32:19 +03001435 if ( ! @imagegif($resource, $this->full_dst_path))
1436 {
1437 $this->set_error('imglib_save_failed');
1438 return FALSE;
1439 }
1440 break;
1441 case 2:
1442 if ( ! function_exists('imagejpeg'))
1443 {
1444 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1445 return FALSE;
1446 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001447
Andrey Andreev56454792012-05-17 14:32:19 +03001448 if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
1449 {
1450 $this->set_error('imglib_save_failed');
1451 return FALSE;
1452 }
1453 break;
1454 case 3:
1455 if ( ! function_exists('imagepng'))
1456 {
1457 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1458 return FALSE;
1459 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001460
Andrey Andreev56454792012-05-17 14:32:19 +03001461 if ( ! @imagepng($resource, $this->full_dst_path))
1462 {
1463 $this->set_error('imglib_save_failed');
1464 return FALSE;
1465 }
1466 break;
1467 default:
1468 $this->set_error(array('imglib_unsupported_imagecreate'));
1469 return FALSE;
1470 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001471 }
1472
1473 return TRUE;
1474 }
1475
1476 // --------------------------------------------------------------------
1477
1478 /**
1479 * Dynamically outputs an image
1480 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001481 * @param resource
1482 * @return void
1483 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001484 public function image_display_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001485 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001486 header('Content-Disposition: filename='.$this->source_image.';');
1487 header('Content-Type: '.$this->mime_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001488 header('Content-Transfer-Encoding: binary');
1489 header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
1490
1491 switch ($this->image_type)
1492 {
Andrey Andreev56454792012-05-17 14:32:19 +03001493 case 1 : imagegif($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001494 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001495 case 2 : imagejpeg($resource, '', $this->quality);
Derek Allard2067d1a2008-11-13 22:59:24 +00001496 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001497 case 3 : imagepng($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001498 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001499 default: echo 'Unable to display the image';
Derek Allard2067d1a2008-11-13 22:59:24 +00001500 break;
1501 }
1502 }
1503
1504 // --------------------------------------------------------------------
1505
1506 /**
1507 * Re-proportion Image Width/Height
1508 *
1509 * When creating thumbs, the desired width/height
1510 * can end up warping the image due to an incorrect
1511 * ratio between the full-sized image and the thumb.
1512 *
1513 * This function lets us re-proportion the width/height
1514 * if users choose to maintain the aspect ratio when resizing.
1515 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001516 * @return void
1517 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001518 public function image_reproportion()
Derek Allard2067d1a2008-11-13 22:59:24 +00001519 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001520 if (($this->width === 0 && $this->height === 0) OR $this->orig_width === 0 OR $this->orig_height === 0
Andrey Andreev8e70b792012-01-12 20:19:24 +02001521 OR ( ! preg_match('/^[0-9]+$/', $this->width) && ! preg_match('/^[0-9]+$/', $this->height))
1522 OR ! preg_match('/^[0-9]+$/', $this->orig_width) OR ! preg_match('/^[0-9]+$/', $this->orig_height))
Derek Allard2067d1a2008-11-13 22:59:24 +00001523 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001524 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001525 }
1526
Andrey Andreev8e70b792012-01-12 20:19:24 +02001527 // Sanitize so we don't call preg_match() anymore
1528 $this->width = (int) $this->width;
1529 $this->height = (int) $this->height;
1530
1531 if ($this->master_dim !== 'width' && $this->master_dim !== 'height')
Derek Allard2067d1a2008-11-13 22:59:24 +00001532 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001533 if ($this->width > 0 && $this->height > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001534 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001535 $this->master_dim = ((($this->orig_height/$this->orig_width) - ($this->height/$this->width)) < 0)
1536 ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001537 }
1538 else
1539 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001540 $this->master_dim = ($this->height === 0) ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001541 }
1542 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001543 elseif (($this->master_dim === 'width' && $this->width === 0)
1544 OR ($this->master_dim === 'height' && $this->height === 0))
1545 {
1546 return;
1547 }
1548
1549 if ($this->master_dim === 'width')
1550 {
1551 $this->height = (int) ceil($this->width*$this->orig_height/$this->orig_width);
1552 }
1553 else
1554 {
1555 $this->width = (int) ceil($this->orig_width*$this->height/$this->orig_height);
1556 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001557 }
1558
1559 // --------------------------------------------------------------------
1560
1561 /**
1562 * Get image properties
1563 *
1564 * A helper function that gets info about the file
1565 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001566 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001567 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001568 * @return mixed
1569 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001570 public function get_image_properties($path = '', $return = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001571 {
1572 // For now we require GD but we should
1573 // find a way to determine this using IM or NetPBM
1574
Alex Bilbied261b1e2012-06-02 11:12:16 +01001575 if ($path === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +02001576 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001577 $path = $this->full_src_path;
Andrey Andreev8e70b792012-01-12 20:19:24 +02001578 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001579
1580 if ( ! file_exists($path))
1581 {
1582 $this->set_error('imglib_invalid_path');
1583 return FALSE;
1584 }
1585
Phil Sturgeon901998a2011-08-26 10:03:33 +01001586 $vals = getimagesize($path);
Derek Allard2067d1a2008-11-13 22:59:24 +00001587 $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
Andrey Andreeva92b9032011-12-24 19:05:58 +02001588 $mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001589
Alex Bilbied261b1e2012-06-02 11:12:16 +01001590 if ($return === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001591 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001592 return array(
1593 'width' => $vals[0],
1594 'height' => $vals[1],
1595 'image_type' => $vals[2],
1596 'size_str' => $vals[3],
1597 'mime_type' => $mime
1598 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001599 }
1600
Andrey Andreeva92b9032011-12-24 19:05:58 +02001601 $this->orig_width = $vals[0];
1602 $this->orig_height = $vals[1];
1603 $this->image_type = $vals[2];
1604 $this->size_str = $vals[3];
Derek Allard2067d1a2008-11-13 22:59:24 +00001605 $this->mime_type = $mime;
1606
1607 return TRUE;
1608 }
1609
1610 // --------------------------------------------------------------------
1611
1612 /**
1613 * Size calculator
1614 *
1615 * This function takes a known width x height and
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001616 * recalculates it to a new size. Only one
Derek Allard2067d1a2008-11-13 22:59:24 +00001617 * new variable needs to be known
1618 *
1619 * $props = array(
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001620 * 'width' => $width,
1621 * 'height' => $height,
1622 * 'new_width' => 40,
1623 * 'new_height' => ''
1624 * );
Derek Allard2067d1a2008-11-13 22:59:24 +00001625 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001626 * @param array
1627 * @return array
1628 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001629 public function size_calculator($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001630 {
1631 if ( ! is_array($vals))
1632 {
1633 return;
1634 }
1635
1636 $allowed = array('new_width', 'new_height', 'width', 'height');
1637
1638 foreach ($allowed as $item)
1639 {
Andrey Andreev56454792012-05-17 14:32:19 +03001640 if (empty($vals[$item]))
1641 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001642 $vals[$item] = 0;
Andrey Andreev56454792012-05-17 14:32:19 +03001643 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001644 }
1645
Alex Bilbied261b1e2012-06-02 11:12:16 +01001646 if ($vals['width'] === 0 OR $vals['height'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001647 {
1648 return $vals;
1649 }
1650
Alex Bilbied261b1e2012-06-02 11:12:16 +01001651 if ($vals['new_width'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001652 {
1653 $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1654 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001655 elseif ($vals['new_height'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001656 {
1657 $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1658 }
1659
1660 return $vals;
1661 }
1662
1663 // --------------------------------------------------------------------
1664
1665 /**
1666 * Explode source_image
1667 *
1668 * This is a helper function that extracts the extension
Derek Jones4b9c6292011-07-01 17:40:48 -05001669 * from the source_image. This function lets us deal with
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001670 * source_images with multiple periods, like: my.cool.jpg
Derek Allard2067d1a2008-11-13 22:59:24 +00001671 * It returns an associative array with two elements:
Derek Jones4b9c6292011-07-01 17:40:48 -05001672 * $array['ext'] = '.jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001673 * $array['name'] = 'my.cool';
1674 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001675 * @param array
1676 * @return array
1677 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001678 public function explode_name($source_image)
Derek Allard2067d1a2008-11-13 22:59:24 +00001679 {
Derek Jones08cae632009-02-10 20:03:29 +00001680 $ext = strrchr($source_image, '.');
1681 $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
Barry Mienydd671972010-10-04 16:33:58 +02001682
Derek Jones08cae632009-02-10 20:03:29 +00001683 return array('ext' => $ext, 'name' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001684 }
1685
1686 // --------------------------------------------------------------------
1687
1688 /**
1689 * Is GD Installed?
1690 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001691 * @return bool
1692 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001693 public function gd_loaded()
Derek Allard2067d1a2008-11-13 22:59:24 +00001694 {
1695 if ( ! extension_loaded('gd'))
1696 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001697 /* As it is stated in the PHP manual, dl() is not always available
1698 * and even if so - it could generate an E_WARNING message on failure
1699 */
Andrey Andreev8e70b792012-01-12 20:19:24 +02001700 return (function_exists('dl') && @dl('gd.so'));
Derek Allard2067d1a2008-11-13 22:59:24 +00001701 }
1702
1703 return TRUE;
1704 }
1705
1706 // --------------------------------------------------------------------
1707
1708 /**
1709 * Get GD version
1710 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001711 * @return mixed
1712 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001713 public function gd_version()
Derek Allard2067d1a2008-11-13 22:59:24 +00001714 {
1715 if (function_exists('gd_info'))
1716 {
1717 $gd_version = @gd_info();
Andrey Andreev8e70b792012-01-12 20:19:24 +02001718 return preg_replace('/\D/', '', $gd_version['GD Version']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001719 }
1720
1721 return FALSE;
1722 }
1723
1724 // --------------------------------------------------------------------
1725
1726 /**
1727 * Set error message
1728 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001729 * @param string
1730 * @return void
1731 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001732 public function set_error($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +00001733 {
1734 $CI =& get_instance();
1735 $CI->lang->load('imglib');
1736
1737 if (is_array($msg))
1738 {
1739 foreach ($msg as $val)
1740 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001741 $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
Derek Allard2067d1a2008-11-13 22:59:24 +00001742 $this->error_msg[] = $msg;
1743 log_message('error', $msg);
1744 }
1745 }
1746 else
1747 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001748 $msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg);
Derek Allard2067d1a2008-11-13 22:59:24 +00001749 $this->error_msg[] = $msg;
1750 log_message('error', $msg);
1751 }
1752 }
1753
1754 // --------------------------------------------------------------------
1755
1756 /**
1757 * Show error messages
1758 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001759 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001760 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001761 * @return string
1762 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001763 public function display_errors($open = '<p>', $close = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +00001764 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001765 return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001766 }
1767
1768}
Derek Allard2067d1a2008-11-13 22:59:24 +00001769
1770/* End of file Image_lib.php */
Andrey Andreev1b815532012-04-03 16:06:03 +03001771/* Location: ./system/libraries/Image_lib.php */