blob: e90f325aefc00914fb00b56f90ad8907dee7e27d [file] [log] [blame]
Andrey Andreeva92b9032011-12-24 19:05:58 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Eric Barnesb1673362011-12-05 22:05:38 -05008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Eric Barnesb1673362011-12-05 22:05:38 -050010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
Andrey Andreeva3d19c42012-01-24 15:29:29 +020012 * bundled with this package in the files license.txt / license.rst. It is
Derek Jonesf4a4bd82011-10-20 12:18:42 -050013 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * Image Manipulation class
30 *
31 * @package CodeIgniter
32 * @subpackage Libraries
33 * @category Image_lib
Derek Jonesf4a4bd82011-10-20 12:18:42 -050034 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000035 * @link http://codeigniter.com/user_guide/libraries/image_lib.html
36 */
37class CI_Image_lib {
38
Timothy Warrenb8e62852012-04-26 18:40:54 -040039 /**
40 * PHP extension/library to use for image manipulation
41 * Can be: imagemagick, netpbm, gd, gd2
42 *
43 * @var string
44 */
45 public $image_library = 'gd2';
46
47 /**
48 * Path to the graphic library (if applicable)
49 *
50 * @var string
51 */
Andrey Andreev3a459572011-12-21 11:23:11 +020052 public $library_path = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040053
54 /**
55 * Whether to send to browser or write to disk
56 *
57 * @var bool
58 */
59 public $dynamic_output = FALSE;
60
61 /**
62 * Path to original image
63 *
64 * @var string
65 */
Andrey Andreev3a459572011-12-21 11:23:11 +020066 public $source_image = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040067
68 /**
69 * Path to the modified image
70 *
71 * @var string
72 */
Andrey Andreev3a459572011-12-21 11:23:11 +020073 public $new_image = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040074
75 /**
76 * Image width
77 *
78 * @var int
79 */
Andrey Andreev3a459572011-12-21 11:23:11 +020080 public $width = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040081
82 /**
83 * Image height
84 *
85 * @var int
86 */
Andrey Andreev3a459572011-12-21 11:23:11 +020087 public $height = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -040088
89 /**
90 * Quality percentage of new image
91 *
92 * @var int
93 */
Andrey Andreev3a459572011-12-21 11:23:11 +020094 public $quality = '90';
Timothy Warrenb8e62852012-04-26 18:40:54 -040095
96 /**
97 * Whether to create a thumbnail
98 *
99 * @var bool
100 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200101 public $create_thumb = FALSE;
Timothy Warrenb8e62852012-04-26 18:40:54 -0400102
103 /**
104 * String to add to thumbnail version of image
105 *
106 * @var string
107 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200108 public $thumb_marker = '_thumb';
Timothy Warrenb8e62852012-04-26 18:40:54 -0400109
110 /**
111 * Whether to maintain aspect ratio when resizing or use hard values
112 *
113 * @var bool
114 */
115 public $maintain_ratio = TRUE;
116
117 /**
118 * auto, height, or width. Determines what to use as the master dimension
119 *
120 * @var string
121 */
122 public $master_dim = 'auto';
123
124 /**
125 * Angle at to rotate image
126 *
127 * @var string
128 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200129 public $rotation_angle = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -0400130
131 /**
132 * X Coordinate for manipulation of the current image
133 *
134 * @var int
135 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200136 public $x_axis = '';
Timothy Warrenb8e62852012-04-26 18:40:54 -0400137
138 /**
139 * Y Coordinate for manipulation of the current image
140 *
141 * @var int
142 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200143 public $y_axis = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000144
Timothy Warrenb8e62852012-04-26 18:40:54 -0400145 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 // Watermark Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400147 // --------------------------------------------------------------------------
148
149 /**
150 * Watermark text if graphic is not used
151 *
152 * @var string
153 */
154 public $wm_text = '';
155
156 /**
157 * Type of watermarking. Options: text/overlay
158 *
159 * @var string
160 */
161 public $wm_type = 'text';
162
163 /**
164 * @var int
165 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200166 public $wm_x_transp = 4;
Timothy Warrenb8e62852012-04-26 18:40:54 -0400167
168 /**
169 * @var int
170 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200171 public $wm_y_transp = 4;
Timothy Warrenb8e62852012-04-26 18:40:54 -0400172
173 /**
174 * Watermark image path
175 *
176 * @var string
177 */
178 public $wm_overlay_path = '';
179
180 /**
181 * TT font
182 *
183 * @var string
184 */
185 public $wm_font_path = '';
186
187 /**
188 * Font size (different versions of GD will either use points or pixels)
189 *
190 * @var int
191 */
192 public $wm_font_size = 17;
193
194 /**
195 * Vertical alignment: T M B
196 *
197 * @var string
198 */
199 public $wm_vrt_alignment = 'B';
200
201 /**
202 * Horizontal alignment: L R C
203 *
204 * @var string
205 */
206 public $wm_hor_alignment = 'C';
207
208 /**
209 * Padding around text
210 *
211 * @var int
212 */
213 public $wm_padding = 0;
214
215 /**
216 * Lets you push text to the right
217 *
218 * @var int
219 */
220 public $wm_hor_offset = 0;
221
222 /**
223 * Lets you push text down
224 *
225 * @var int
226 */
227 public $wm_vrt_offset = 0;
228
229 /**
230 * Text color
231 *
232 * @var string
233 */
234 protected $wm_font_color = '#ffffff';
235
236 /**
237 * Dropshadow color
238 *
239 * @var string
240 */
241 protected $wm_shadow_color = '';
242
243 /**
244 * Dropshadow distance
245 *
246 * @var int
247 */
248 public $wm_shadow_distance = 2;
249
250 /**
251 * Image opacity: 1 - 100 Only works with image
252 *
253 * @var int
254 */
255 public $wm_opacity = 50;
Derek Allard2067d1a2008-11-13 22:59:24 +0000256
Timothy Warrenb8e62852012-04-26 18:40:54 -0400257 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 // Private Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400259 // --------------------------------------------------------------------------
260
Andrey Andreev3a459572011-12-21 11:23:11 +0200261 public $source_folder = '';
262 public $dest_folder = '';
263 public $mime_type = '';
264 public $orig_width = '';
265 public $orig_height = '';
266 public $image_type = '';
267 public $size_str = '';
268 public $full_src_path = '';
269 public $full_dst_path = '';
270 public $create_fnc = 'imagecreatetruecolor';
271 public $copy_fnc = 'imagecopyresampled';
272 public $error_msg = array();
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200273 protected $wm_use_drop_shadow = FALSE;
Andrey Andreev3a459572011-12-21 11:23:11 +0200274 public $wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000275
Greg Akera9263282010-11-10 15:26:43 -0600276 public function __construct($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 {
278 if (count($props) > 0)
279 {
280 $this->initialize($props);
281 }
282
Andrey Andreev8e70b792012-01-12 20:19:24 +0200283 log_message('debug', 'Image Lib Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 }
285
286 // --------------------------------------------------------------------
287
288 /**
289 * Initialize image properties
290 *
291 * Resets values in case this class is used in a loop
292 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 * @return void
294 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200295 public function clear()
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 {
Michael Denniscb07a322011-08-20 23:40:59 -0700297 $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 +0000298
299 foreach ($props as $val)
300 {
301 $this->$val = '';
302 }
303
Michael Denniscb07a322011-08-20 23:40:59 -0700304 $this->image_library = 'gd2';
305 $this->dynamic_output = FALSE;
306 $this->quality = '90';
307 $this->create_thumb = FALSE;
308 $this->thumb_marker = '_thumb';
309 $this->maintain_ratio = TRUE;
310 $this->master_dim = 'auto';
311 $this->wm_type = 'text';
312 $this->wm_x_transp = 4;
313 $this->wm_y_transp = 4;
314 $this->wm_font_size = 17;
315 $this->wm_vrt_alignment = 'B';
316 $this->wm_hor_alignment = 'C';
317 $this->wm_padding = 0;
318 $this->wm_hor_offset = 0;
319 $this->wm_vrt_offset = 0;
320 $this->wm_font_color = '#ffffff';
321 $this->wm_shadow_distance = 2;
322 $this->wm_opacity = 50;
323 $this->create_fnc = 'imagecreatetruecolor';
324 $this->copy_fnc = 'imagecopyresampled';
325 $this->error_msg = array();
326 $this->wm_use_drop_shadow = FALSE;
327 $this->wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 }
329
330 // --------------------------------------------------------------------
331
332 /**
333 * initialize image preferences
334 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 * @param array
336 * @return bool
337 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200338 public function initialize($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200340 // Convert array elements into class variables
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 if (count($props) > 0)
342 {
343 foreach ($props as $key => $val)
344 {
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200345 if (property_exists($this, $key))
346 {
347 if (in_array($key, array('wm_font_color', 'wm_shadow_color')))
348 {
Andrey Andreev8323ae62011-12-31 18:39:10 +0200349 if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200350 {
Andrey Andreevcf2ba9e2012-01-01 21:57:13 +0200351 /* $matches[1] contains our hex color value, but it might be
Andrey Andreev8323ae62011-12-31 18:39:10 +0200352 * both in the full 6-length format or the shortened 3-length
353 * value.
Andrey Andreevbb96c8b2011-12-31 18:48:39 +0200354 * We'll later need the full version, so we keep it if it's
Andrey Andreev8323ae62011-12-31 18:39:10 +0200355 * already there and if not - we'll convert to it. We can
356 * access string characters by their index as in an array,
357 * so we'll do that and use concatenation to form the final
358 * value:
359 */
Andrey Andreev665af0c2011-12-30 14:39:29 +0200360 $val = (strlen($matches[1]) === 6)
361 ? '#'.$matches[1]
362 : '#'.$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 +0200363 }
364 else
365 {
366 continue;
367 }
368 }
369
370 $this->$key = $val;
371 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 }
373 }
374
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200375 // Is there a source image? If not, there's no reason to continue
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 if ($this->source_image == '')
377 {
378 $this->set_error('imglib_source_image_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500379 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000380 }
381
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200382 /* Is getimagesize() available?
Derek Allard2067d1a2008-11-13 22:59:24 +0000383 *
384 * We use it to determine the image properties (width/height).
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200385 * Note: We need to figure out how to determine image
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 * properties using ImageMagick and NetPBM
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 */
388 if ( ! function_exists('getimagesize'))
389 {
390 $this->set_error('imglib_gd_required_for_props');
391 return FALSE;
392 }
393
394 $this->image_library = strtolower($this->image_library);
395
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200396 /* Set the full server path
Derek Allard2067d1a2008-11-13 22:59:24 +0000397 *
398 * The source image may or may not contain a path.
399 * Either way, we'll try use realpath to generate the
400 * full server path in order to more reliably read it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000401 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200402 if (function_exists('realpath') && @realpath($this->source_image) !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200404 $full_source_path = str_replace('\\', '/', realpath($this->source_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000405 }
406 else
407 {
408 $full_source_path = $this->source_image;
409 }
410
411 $x = explode('/', $full_source_path);
412 $this->source_image = end($x);
413 $this->source_folder = str_replace($this->source_image, '', $full_source_path);
414
415 // Set the Image Properties
416 if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
417 {
Eric Barnesb1673362011-12-05 22:05:38 -0500418 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 }
420
421 /*
422 * Assign the "new" image name/path
423 *
424 * If the user has set a "new_image" name it means
425 * we are making a copy of the source image. If not
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200426 * it means we are altering the original. We'll
Derek Allard2067d1a2008-11-13 22:59:24 +0000427 * set the destination filename and path accordingly.
Derek Allard2067d1a2008-11-13 22:59:24 +0000428 */
429 if ($this->new_image == '')
430 {
431 $this->dest_image = $this->source_image;
432 $this->dest_folder = $this->source_folder;
433 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200434 elseif (strpos($this->new_image, '/') === FALSE)
435 {
436 $this->dest_folder = $this->source_folder;
437 $this->dest_image = $this->new_image;
438 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 else
440 {
Andrey Andreev1b815532012-04-03 16:06:03 +0300441 if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200443 $full_dest_path = str_replace('\\', '/', realpath($this->new_image));
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 }
445 else
446 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200447 $full_dest_path = $this->new_image;
448 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000449
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200450 // Is there a file name?
451 if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path))
452 {
453 $this->dest_folder = $full_dest_path.'/';
454 $this->dest_image = $this->source_image;
455 }
456 else
457 {
458 $x = explode('/', $full_dest_path);
459 $this->dest_image = end($x);
460 $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 }
462 }
463
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200464 /* Compile the finalized filenames/paths
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 *
466 * We'll create two master strings containing the
467 * full server path to the source image and the
468 * full server path to the destination image.
469 * We'll also split the destination image name
470 * so we can insert the thumbnail marker if needed.
Derek Allard2067d1a2008-11-13 22:59:24 +0000471 */
472 if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
473 {
474 $this->thumb_marker = '';
475 }
476
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200477 $xp = $this->explode_name($this->dest_image);
Derek Allard2067d1a2008-11-13 22:59:24 +0000478
479 $filename = $xp['name'];
480 $file_ext = $xp['ext'];
481
482 $this->full_src_path = $this->source_folder.$this->source_image;
483 $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
484
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200485 /* Should we maintain image proportions?
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 *
487 * When creating thumbs or copies, the target width/height
488 * might not be in correct proportion with the source
Andrey Andreev8e70b792012-01-12 20:19:24 +0200489 * image's width/height. We'll recalculate it here.
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200491 if ($this->maintain_ratio === TRUE && ($this->width != 0 OR $this->height != 0))
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 {
493 $this->image_reproportion();
494 }
495
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200496 /* Was a width and height specified?
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 *
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200498 * If the destination width/height was not submitted we
499 * will use the values from the actual file
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 */
501 if ($this->width == '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200502 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000503 $this->width = $this->orig_width;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200504 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000505
506 if ($this->height == '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200507 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000508 $this->height = $this->orig_height;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200509 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000510
511 // Set the quality
Andrey Andreev8e70b792012-01-12 20:19:24 +0200512 $this->quality = trim(str_replace('%', '', $this->quality));
Derek Allard2067d1a2008-11-13 22:59:24 +0000513
Andrey Andreev8e70b792012-01-12 20:19:24 +0200514 if ($this->quality == '' OR $this->quality == 0 OR ! preg_match('/^[0-9]+$/', $this->quality))
515 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000516 $this->quality = 90;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200517 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000518
519 // Set the x/y coordinates
Andrey Andreev8e70b792012-01-12 20:19:24 +0200520 $this->x_axis = ($this->x_axis == '' OR ! preg_match('/^[0-9]+$/', $this->x_axis)) ? 0 : $this->x_axis;
521 $this->y_axis = ($this->y_axis == '' OR ! preg_match('/^[0-9]+$/', $this->y_axis)) ? 0 : $this->y_axis;
Derek Allard2067d1a2008-11-13 22:59:24 +0000522
523 // Watermark-related Stuff...
Derek Allard2067d1a2008-11-13 22:59:24 +0000524 if ($this->wm_overlay_path != '')
525 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200526 $this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 }
528
529 if ($this->wm_shadow_color != '')
530 {
531 $this->wm_use_drop_shadow = TRUE;
532 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200533 elseif ($this->wm_use_drop_shadow == TRUE && $this->wm_shadow_color == '')
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200534 {
535 $this->wm_use_drop_shadow = FALSE;
536 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000537
538 if ($this->wm_font_path != '')
539 {
540 $this->wm_use_truetype = TRUE;
541 }
542
543 return TRUE;
544 }
545
546 // --------------------------------------------------------------------
547
548 /**
549 * Image Resize
550 *
551 * This is a wrapper function that chooses the proper
552 * resize function based on the protocol specified
553 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000554 * @return bool
555 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200556 public function resize()
Derek Allard2067d1a2008-11-13 22:59:24 +0000557 {
Andrey Andreev1a9f52c2012-01-07 01:06:34 +0200558 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000559 return $this->$protocol('resize');
560 }
561
562 // --------------------------------------------------------------------
563
564 /**
565 * Image Crop
566 *
567 * This is a wrapper function that chooses the proper
568 * cropping function based on the protocol specified
569 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000570 * @return bool
571 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200572 public function crop()
Derek Allard2067d1a2008-11-13 22:59:24 +0000573 {
Andrey Andreev5a67e3d2012-01-07 01:21:09 +0200574 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000575 return $this->$protocol('crop');
576 }
577
578 // --------------------------------------------------------------------
579
580 /**
581 * Image Rotate
582 *
583 * This is a wrapper function that chooses the proper
584 * rotation function based on the protocol specified
585 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000586 * @return bool
587 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200588 public function rotate()
Derek Allard2067d1a2008-11-13 22:59:24 +0000589 {
590 // Allowed rotation values
591 $degs = array(90, 180, 270, 'vrt', 'hor');
592
Derek Allardd9c7f032008-12-01 20:18:00 +0000593 if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs))
Derek Allard2067d1a2008-11-13 22:59:24 +0000594 {
595 $this->set_error('imglib_rotation_angle_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500596 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000597 }
598
599 // Reassign the width and height
600 if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)
601 {
602 $this->width = $this->orig_height;
603 $this->height = $this->orig_width;
604 }
605 else
606 {
607 $this->width = $this->orig_width;
608 $this->height = $this->orig_height;
609 }
610
Derek Allard2067d1a2008-11-13 22:59:24 +0000611 // Choose resizing function
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200612 if ($this->image_library === 'imagemagick' OR $this->image_library === 'netpbm')
Derek Allard2067d1a2008-11-13 22:59:24 +0000613 {
614 $protocol = 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000615 return $this->$protocol('rotate');
616 }
617
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200618 return ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
619 ? $this->image_mirror_gd()
620 : $this->image_rotate_gd();
Derek Allard2067d1a2008-11-13 22:59:24 +0000621 }
622
623 // --------------------------------------------------------------------
624
625 /**
626 * Image Process Using GD/GD2
627 *
628 * This function will resize or crop
629 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000630 * @param string
631 * @return bool
632 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200633 public function image_process_gd($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000634 {
635 $v2_override = FALSE;
636
637 // If the target width/height match the source, AND if the new file name is not equal to the old file name
638 // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
Andrey Andreev8e70b792012-01-12 20:19:24 +0200639 if ($this->dynamic_output === FALSE && $this->orig_width == $this->width && $this->orig_height == $this->height)
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200641 if ($this->source_image != $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000642 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200643 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000644 }
Andrey Andreeva92b9032011-12-24 19:05:58 +0200645
646 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000647 }
648
649 // Let's set up our values based on the action
650 if ($action == 'crop')
651 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200652 // Reassign the source width/height if cropping
Derek Jones4b9c6292011-07-01 17:40:48 -0500653 $this->orig_width = $this->width;
Derek Allard2067d1a2008-11-13 22:59:24 +0000654 $this->orig_height = $this->height;
655
656 // GD 2.0 has a cropping bug so we'll test for it
657 if ($this->gd_version() !== FALSE)
658 {
659 $gd_version = str_replace('0', '', $this->gd_version());
660 $v2_override = ($gd_version == 2) ? TRUE : FALSE;
661 }
662 }
663 else
664 {
665 // If resizing the x/y axis must be zero
666 $this->x_axis = 0;
667 $this->y_axis = 0;
668 }
669
Derek Jones4b9c6292011-07-01 17:40:48 -0500670 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000671 if ( ! ($src_img = $this->image_create_gd()))
672 {
673 return FALSE;
674 }
675
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200676 /* Create the image
677 *
678 * Old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
679 * it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
680 * below should that ever prove inaccurate.
681 *
682 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override == FALSE)
683 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200684 if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000685 {
686 $create = 'imagecreatetruecolor';
687 $copy = 'imagecopyresampled';
688 }
689 else
690 {
691 $create = 'imagecreate';
692 $copy = 'imagecopyresized';
693 }
694
695 $dst_img = $create($this->width, $this->height);
Derek Jones595bfd12010-08-20 10:28:22 -0500696
697 if ($this->image_type == 3) // png we can actually preserve transparency
698 {
699 imagealphablending($dst_img, FALSE);
700 imagesavealpha($dst_img, TRUE);
701 }
Barry Mienydd671972010-10-04 16:33:58 +0200702
Derek Allard2067d1a2008-11-13 22:59:24 +0000703 $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
704
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200705 // Show the image
Derek Allard2067d1a2008-11-13 22:59:24 +0000706 if ($this->dynamic_output == TRUE)
707 {
708 $this->image_display_gd($dst_img);
709 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200710 elseif ( ! $this->image_save_gd($dst_img)) // Or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000711 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200712 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000713 }
714
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200715 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000716 imagedestroy($dst_img);
717 imagedestroy($src_img);
718
719 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000720 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000721
722 return TRUE;
723 }
724
725 // --------------------------------------------------------------------
726
727 /**
728 * Image Process Using ImageMagick
729 *
730 * This function will resize, crop or rotate
731 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000732 * @param string
733 * @return bool
734 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200735 public function image_process_imagemagick($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000736 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500737 // Do we have a vaild library path?
Derek Allard2067d1a2008-11-13 22:59:24 +0000738 if ($this->library_path == '')
739 {
740 $this->set_error('imglib_libpath_invalid');
741 return FALSE;
742 }
743
Andrey Andreev8e70b792012-01-12 20:19:24 +0200744 if ( ! preg_match('/convert$/i', $this->library_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000745 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200746 $this->library_path = rtrim($this->library_path, '/').'/convert';
Derek Allard2067d1a2008-11-13 22:59:24 +0000747 }
748
749 // Execute the command
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200750 $cmd = $this->library_path.' -quality '.$this->quality;
Derek Allard2067d1a2008-11-13 22:59:24 +0000751
752 if ($action == 'crop')
753 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200754 $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 +0000755 }
756 elseif ($action == 'rotate')
757 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200758 $angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
759 ? '-flop' : '-rotate '.$this->rotation_angle;
Derek Allard2067d1a2008-11-13 22:59:24 +0000760
Andrey Andreev8e70b792012-01-12 20:19:24 +0200761 $cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000762 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200763 else // Resize
Derek Allard2067d1a2008-11-13 22:59:24 +0000764 {
Andrey Andreeve4636302012-01-12 20:23:27 +0200765 $cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
Derek Allard2067d1a2008-11-13 22:59:24 +0000766 }
767
768 $retval = 1;
Derek Allard2067d1a2008-11-13 22:59:24 +0000769 @exec($cmd, $output, $retval);
770
Andrey Andreev8e70b792012-01-12 20:19:24 +0200771 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000772 if ($retval > 0)
773 {
774 $this->set_error('imglib_image_process_failed');
775 return FALSE;
776 }
777
778 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000779 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000780
781 return TRUE;
782 }
783
784 // --------------------------------------------------------------------
785
786 /**
787 * Image Process Using NetPBM
788 *
789 * This function will resize, crop or rotate
790 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000791 * @param string
792 * @return bool
793 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200794 public function image_process_netpbm($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000795 {
796 if ($this->library_path == '')
797 {
798 $this->set_error('imglib_libpath_invalid');
799 return FALSE;
800 }
801
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200802 // Build the resizing command
Derek Allard2067d1a2008-11-13 22:59:24 +0000803 switch ($this->image_type)
804 {
805 case 1 :
806 $cmd_in = 'giftopnm';
807 $cmd_out = 'ppmtogif';
808 break;
809 case 2 :
810 $cmd_in = 'jpegtopnm';
811 $cmd_out = 'ppmtojpeg';
812 break;
813 case 3 :
814 $cmd_in = 'pngtopnm';
815 $cmd_out = 'ppmtopng';
816 break;
817 }
818
819 if ($action == 'crop')
820 {
821 $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
822 }
823 elseif ($action == 'rotate')
824 {
825 switch ($this->rotation_angle)
826 {
827 case 90 : $angle = 'r270';
828 break;
829 case 180 : $angle = 'r180';
830 break;
Barry Mienydd671972010-10-04 16:33:58 +0200831 case 270 : $angle = 'r90';
Derek Allard2067d1a2008-11-13 22:59:24 +0000832 break;
833 case 'vrt' : $angle = 'tb';
834 break;
835 case 'hor' : $angle = 'lr';
836 break;
837 }
838
839 $cmd_inner = 'pnmflip -'.$angle.' ';
840 }
841 else // Resize
842 {
843 $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
844 }
845
846 $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
847
848 $retval = 1;
Derek Allard2067d1a2008-11-13 22:59:24 +0000849 @exec($cmd, $output, $retval);
850
Andrey Andreev8e70b792012-01-12 20:19:24 +0200851 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000852 if ($retval > 0)
853 {
854 $this->set_error('imglib_image_process_failed');
855 return FALSE;
856 }
857
858 // With NetPBM we have to create a temporary image.
859 // If you try manipulating the original it fails so
860 // we have to rename the temp file.
861 copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200862 unlink($this->dest_folder.'netpbm.tmp');
Derek Jones172e1612009-10-13 14:32:48 +0000863 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000864
865 return TRUE;
866 }
867
868 // --------------------------------------------------------------------
869
870 /**
871 * Image Rotate Using GD
872 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000873 * @return bool
874 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200875 public function image_rotate_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +0000876 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200877 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000878 if ( ! ($src_img = $this->image_create_gd()))
879 {
880 return FALSE;
881 }
882
883 // Set the background color
884 // This won't work with transparent PNG files so we are
885 // going to have to figure out how to determine the color
886 // of the alpha channel in a future release.
887
888 $white = imagecolorallocate($src_img, 255, 255, 255);
889
Andrey Andreev8e70b792012-01-12 20:19:24 +0200890 // Rotate it!
Derek Allard2067d1a2008-11-13 22:59:24 +0000891 $dst_img = imagerotate($src_img, $this->rotation_angle, $white);
892
Andrey Andreev8e70b792012-01-12 20:19:24 +0200893 // Show the image
Derek Allard2067d1a2008-11-13 22:59:24 +0000894 if ($this->dynamic_output == TRUE)
895 {
896 $this->image_display_gd($dst_img);
897 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200898 elseif ( ! $this->image_save_gd($dst_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000899 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200900 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000901 }
902
Andrey Andreev8e70b792012-01-12 20:19:24 +0200903 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000904 imagedestroy($dst_img);
905 imagedestroy($src_img);
906
907 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000908 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000909
Pascal Kriete8761ef52011-02-14 13:13:52 -0500910 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000911 }
912
913 // --------------------------------------------------------------------
914
915 /**
916 * Create Mirror Image using GD
917 *
918 * This function will flip horizontal or vertical
919 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000920 * @return bool
921 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200922 public function image_mirror_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +0000923 {
924 if ( ! $src_img = $this->image_create_gd())
925 {
926 return FALSE;
927 }
928
Derek Jones4b9c6292011-07-01 17:40:48 -0500929 $width = $this->orig_width;
Derek Allard2067d1a2008-11-13 22:59:24 +0000930 $height = $this->orig_height;
931
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200932 if ($this->rotation_angle === 'hor')
Derek Allard2067d1a2008-11-13 22:59:24 +0000933 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200934 for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000935 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000936 while ($left < $right)
937 {
938 $cl = imagecolorat($src_img, $left, $i);
939 $cr = imagecolorat($src_img, $right, $i);
940
941 imagesetpixel($src_img, $left, $i, $cr);
942 imagesetpixel($src_img, $right, $i, $cl);
943
944 $left++;
945 $right--;
946 }
947 }
948 }
949 else
950 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200951 for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000952 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000953 while ($top < $bot)
954 {
955 $ct = imagecolorat($src_img, $i, $top);
956 $cb = imagecolorat($src_img, $i, $bot);
957
958 imagesetpixel($src_img, $i, $top, $cb);
959 imagesetpixel($src_img, $i, $bot, $ct);
960
961 $top++;
962 $bot--;
963 }
964 }
965 }
966
Andrey Andreev8e70b792012-01-12 20:19:24 +0200967 // Show the image
Derek Allard2067d1a2008-11-13 22:59:24 +0000968 if ($this->dynamic_output == TRUE)
969 {
970 $this->image_display_gd($src_img);
971 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200972 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000973 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200974 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000975 }
976
Andrey Andreev8e70b792012-01-12 20:19:24 +0200977 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000978 imagedestroy($src_img);
979
980 // Set the file to 777
Derek Jones172e1612009-10-13 14:32:48 +0000981 @chmod($this->full_dst_path, FILE_WRITE_MODE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000982
983 return TRUE;
984 }
985
986 // --------------------------------------------------------------------
987
988 /**
989 * Image Watermark
990 *
991 * This is a wrapper function that chooses the type
992 * of watermarking based on the specified preference.
993 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000994 * @param string
995 * @return bool
996 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200997 public function watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +0000998 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200999 return ($this->wm_type === 'overlay') ? $this->overlay_watermark() : $this->text_watermark();
Derek Allard2067d1a2008-11-13 22:59:24 +00001000 }
1001
1002 // --------------------------------------------------------------------
1003
1004 /**
1005 * Watermark - Graphic Version
1006 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001007 * @return bool
1008 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001009 public function overlay_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001010 {
1011 if ( ! function_exists('imagecolortransparent'))
1012 {
1013 $this->set_error('imglib_gd_required');
1014 return FALSE;
1015 }
1016
Andrey Andreev8e70b792012-01-12 20:19:24 +02001017 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001018 $this->get_image_properties();
1019
Andrey Andreev8e70b792012-01-12 20:19:24 +02001020 // Fetch watermark image properties
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001021 $props = $this->get_image_properties($this->wm_overlay_path, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001022 $wm_img_type = $props['image_type'];
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001023 $wm_width = $props['width'];
1024 $wm_height = $props['height'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001025
Andrey Andreev8e70b792012-01-12 20:19:24 +02001026 // Create two image resources
Derek Jones4b9c6292011-07-01 17:40:48 -05001027 $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001028 $src_img = $this->image_create_gd($this->full_src_path);
1029
1030 // Reverse the offset if necessary
1031 // When the image is positioned at the bottom
1032 // we don't want the vertical offset to push it
Andrey Andreev8e70b792012-01-12 20:19:24 +02001033 // further down. We want the reverse, so we'll
1034 // invert the offset. Same with the horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001035 // offset when the image is at the right
1036
Andrey Andreev8e70b792012-01-12 20:19:24 +02001037 $this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
1038 $this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001039
1040 if ($this->wm_vrt_alignment == 'B')
1041 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1042
1043 if ($this->wm_hor_alignment == 'R')
1044 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1045
Andrey Andreev8e70b792012-01-12 20:19:24 +02001046 // Set the base x and y axis values
Derek Allard2067d1a2008-11-13 22:59:24 +00001047 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1048 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1049
Andrey Andreev8e70b792012-01-12 20:19:24 +02001050 // Set the vertical position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001051 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001052 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001053 $y_axis += ($this->orig_height / 2) - ($wm_height / 2);
1054 }
1055 elseif ($this->wm_vrt_alignment === 'B')
1056 {
1057 $y_axis += $this->orig_height - $wm_height;
Derek Allard2067d1a2008-11-13 22:59:24 +00001058 }
1059
Andrey Andreev8e70b792012-01-12 20:19:24 +02001060 // Set the horizontal position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001061 if ($this->wm_hor_alignment === 'C')
Derek Allard2067d1a2008-11-13 22:59:24 +00001062 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001063 $x_axis += ($this->orig_width / 2) - ($wm_width / 2);
1064 }
1065 elseif ($this->wm_hor_alignment === 'R')
1066 {
1067 $x_axis += $this->orig_width - $wm_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001068 }
1069
Derek Jones4b9c6292011-07-01 17:40:48 -05001070 // Build the finalized image
Andrey Andreev8e70b792012-01-12 20:19:24 +02001071 if ($wm_img_type == 3 && function_exists('imagealphablending'))
Derek Allard2067d1a2008-11-13 22:59:24 +00001072 {
1073 @imagealphablending($src_img, TRUE);
Barry Mienydd671972010-10-04 16:33:58 +02001074 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001075
1076 // Set RGB values for text and shadow
1077 $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
1078 $alpha = ($rgba & 0x7F000000) >> 24;
1079
1080 // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1081 if ($alpha > 0)
1082 {
1083 // copy the image directly, the image's alpha transparency being the sole determinant of blending
1084 imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
1085 }
1086 else
1087 {
1088 // set our RGB value from above to be transparent and merge the images with the specified opacity
1089 imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
1090 imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
1091 }
1092
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001093 // Output the image
Derek Allard2067d1a2008-11-13 22:59:24 +00001094 if ($this->dynamic_output == TRUE)
1095 {
1096 $this->image_display_gd($src_img);
1097 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001098 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001099 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001100 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001101 }
1102
1103 imagedestroy($src_img);
1104 imagedestroy($wm_img);
1105
1106 return TRUE;
1107 }
1108
1109 // --------------------------------------------------------------------
1110
1111 /**
1112 * Watermark - Text Version
1113 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001114 * @return bool
1115 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001116 public function text_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001117 {
1118 if ( ! ($src_img = $this->image_create_gd()))
1119 {
1120 return FALSE;
1121 }
1122
Andrey Andreev8e70b792012-01-12 20:19:24 +02001123 if ($this->wm_use_truetype == TRUE && ! file_exists($this->wm_font_path))
Derek Allard2067d1a2008-11-13 22:59:24 +00001124 {
1125 $this->set_error('imglib_missing_font');
1126 return FALSE;
1127 }
1128
Andrey Andreev8e70b792012-01-12 20:19:24 +02001129 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001130 $this->get_image_properties();
1131
Derek Allard2067d1a2008-11-13 22:59:24 +00001132 // Reverse the vertical offset
1133 // When the image is positioned at the bottom
1134 // we don't want the vertical offset to push it
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001135 // further down. We want the reverse, so we'll
Andrey Andreev8e70b792012-01-12 20:19:24 +02001136 // invert the offset. Note: The horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001137 // offset flips itself automatically
1138
1139 if ($this->wm_vrt_alignment == 'B')
1140 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1141
1142 if ($this->wm_hor_alignment == 'R')
1143 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1144
1145 // Set font width and height
1146 // These are calculated differently depending on
1147 // whether we are using the true type font or not
1148 if ($this->wm_use_truetype == TRUE)
1149 {
1150 if ($this->wm_font_size == '')
Andrey Andreeva92b9032011-12-24 19:05:58 +02001151 {
1152 $this->wm_font_size = 17;
1153 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001154
Derek Jones4b9c6292011-07-01 17:40:48 -05001155 $fontwidth = $this->wm_font_size-($this->wm_font_size/4);
Derek Allard2067d1a2008-11-13 22:59:24 +00001156 $fontheight = $this->wm_font_size;
1157 $this->wm_vrt_offset += $this->wm_font_size;
1158 }
1159 else
1160 {
Derek Jones4b9c6292011-07-01 17:40:48 -05001161 $fontwidth = imagefontwidth($this->wm_font_size);
Derek Allard2067d1a2008-11-13 22:59:24 +00001162 $fontheight = imagefontheight($this->wm_font_size);
1163 }
1164
1165 // Set base X and Y axis values
1166 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1167 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1168
Derek Allard2067d1a2008-11-13 22:59:24 +00001169 if ($this->wm_use_drop_shadow == FALSE)
1170 $this->wm_shadow_distance = 0;
1171
1172 $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
1173 $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
1174
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001175 // Set verticle alignment
1176 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001177 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001178 $y_axis += ($this->orig_height / 2) + ($fontheight / 2);
1179 }
1180 elseif ($this->wm_vrt_alignment === 'B')
1181 {
1182 $y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2);
Derek Allard2067d1a2008-11-13 22:59:24 +00001183 }
1184
1185 $x_shad = $x_axis + $this->wm_shadow_distance;
1186 $y_shad = $y_axis + $this->wm_shadow_distance;
1187
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001188 if ($this->wm_use_drop_shadow)
Derek Allard2067d1a2008-11-13 22:59:24 +00001189 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001190 // Set horizontal alignment
1191 if ($this->wm_hor_alignment === 'R')
1192 {
1193 $x_shad += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1194 $x_axis += $this->orig_width - ($fontwidth * strlen($this->wm_text));
1195 }
1196 elseif ($this->wm_hor_alignment === 'C')
1197 {
1198 $x_shad += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1199 $x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1200 }
1201
Andrey Andreev8323ae62011-12-31 18:39:10 +02001202 /* Set RGB values for text and shadow
1203 *
1204 * First character is #, so we don't really need it.
1205 * Get the rest of the string and split it into 2-length
1206 * hex values:
1207 */
1208 $txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001209 $txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
Andrey Andreev8323ae62011-12-31 18:39:10 +02001210 $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
Ronald Beilsma8f80bc42012-01-12 16:41:49 +01001211 $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001212
Andrey Andreev8e70b792012-01-12 20:19:24 +02001213 // Add the text to the source image
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001214 if ($this->wm_use_truetype)
1215 {
1216 imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
1217 imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
1218 }
1219 else
1220 {
1221 imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
1222 imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
1223 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001224 }
1225
Andrey Andreev8e70b792012-01-12 20:19:24 +02001226 // Output the final image
Derek Allard2067d1a2008-11-13 22:59:24 +00001227 if ($this->dynamic_output == TRUE)
1228 {
1229 $this->image_display_gd($src_img);
1230 }
1231 else
1232 {
1233 $this->image_save_gd($src_img);
1234 }
1235
1236 imagedestroy($src_img);
1237
1238 return TRUE;
1239 }
1240
1241 // --------------------------------------------------------------------
1242
1243 /**
1244 * Create Image - GD
1245 *
1246 * This simply creates an image resource handle
1247 * based on the type of image being processed
1248 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001249 * @param string
1250 * @return resource
1251 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001252 public function image_create_gd($path = '', $image_type = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001253 {
1254 if ($path == '')
1255 $path = $this->full_src_path;
1256
1257 if ($image_type == '')
1258 $image_type = $this->image_type;
1259
1260
1261 switch ($image_type)
1262 {
1263 case 1 :
1264 if ( ! function_exists('imagecreatefromgif'))
1265 {
1266 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1267 return FALSE;
1268 }
1269
1270 return imagecreatefromgif($path);
1271 break;
1272 case 2 :
1273 if ( ! function_exists('imagecreatefromjpeg'))
1274 {
1275 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1276 return FALSE;
1277 }
1278
1279 return imagecreatefromjpeg($path);
1280 break;
1281 case 3 :
1282 if ( ! function_exists('imagecreatefrompng'))
1283 {
1284 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1285 return FALSE;
1286 }
1287
1288 return imagecreatefrompng($path);
1289 break;
1290
1291 }
1292
1293 $this->set_error(array('imglib_unsupported_imagecreate'));
1294 return FALSE;
1295 }
1296
1297 // --------------------------------------------------------------------
1298
1299 /**
1300 * Write image file to disk - GD
1301 *
1302 * Takes an image resource as input and writes the file
1303 * to the specified destination
1304 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001305 * @param resource
1306 * @return bool
1307 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001308 public function image_save_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001309 {
1310 switch ($this->image_type)
1311 {
1312 case 1 :
1313 if ( ! function_exists('imagegif'))
1314 {
1315 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1316 return FALSE;
1317 }
1318
Derek Jones541ddbd2008-12-09 15:25:31 +00001319 if ( ! @imagegif($resource, $this->full_dst_path))
1320 {
1321 $this->set_error('imglib_save_failed');
1322 return FALSE;
1323 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001324 break;
1325 case 2 :
1326 if ( ! function_exists('imagejpeg'))
1327 {
1328 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1329 return FALSE;
1330 }
1331
Derek Jones541ddbd2008-12-09 15:25:31 +00001332 if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
1333 {
1334 $this->set_error('imglib_save_failed');
1335 return FALSE;
1336 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001337 break;
1338 case 3 :
1339 if ( ! function_exists('imagepng'))
1340 {
1341 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1342 return FALSE;
1343 }
1344
Derek Jones541ddbd2008-12-09 15:25:31 +00001345 if ( ! @imagepng($resource, $this->full_dst_path))
1346 {
1347 $this->set_error('imglib_save_failed');
1348 return FALSE;
1349 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001350 break;
1351 default :
1352 $this->set_error(array('imglib_unsupported_imagecreate'));
1353 return FALSE;
1354 break;
1355 }
1356
1357 return TRUE;
1358 }
1359
1360 // --------------------------------------------------------------------
1361
1362 /**
1363 * Dynamically outputs an image
1364 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001365 * @param resource
1366 * @return void
1367 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001368 public function image_display_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001369 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001370 header('Content-Disposition: filename='.$this->source_image.';');
1371 header('Content-Type: '.$this->mime_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001372 header('Content-Transfer-Encoding: binary');
1373 header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
1374
1375 switch ($this->image_type)
1376 {
Barry Mienydd671972010-10-04 16:33:58 +02001377 case 1 : imagegif($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001378 break;
1379 case 2 : imagejpeg($resource, '', $this->quality);
1380 break;
1381 case 3 : imagepng($resource);
1382 break;
1383 default : echo 'Unable to display the image';
1384 break;
1385 }
1386 }
1387
1388 // --------------------------------------------------------------------
1389
1390 /**
1391 * Re-proportion Image Width/Height
1392 *
1393 * When creating thumbs, the desired width/height
1394 * can end up warping the image due to an incorrect
1395 * ratio between the full-sized image and the thumb.
1396 *
1397 * This function lets us re-proportion the width/height
1398 * if users choose to maintain the aspect ratio when resizing.
1399 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001400 * @return void
1401 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001402 public function image_reproportion()
Derek Allard2067d1a2008-11-13 22:59:24 +00001403 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001404 if (($this->width == 0 && $this->height == 0) OR $this->orig_width == 0 OR $this->orig_height == 0
1405 OR ( ! preg_match('/^[0-9]+$/', $this->width) && ! preg_match('/^[0-9]+$/', $this->height))
1406 OR ! preg_match('/^[0-9]+$/', $this->orig_width) OR ! preg_match('/^[0-9]+$/', $this->orig_height))
Derek Allard2067d1a2008-11-13 22:59:24 +00001407 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001408 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001409 }
1410
Andrey Andreev8e70b792012-01-12 20:19:24 +02001411 // Sanitize so we don't call preg_match() anymore
1412 $this->width = (int) $this->width;
1413 $this->height = (int) $this->height;
1414
1415 if ($this->master_dim !== 'width' && $this->master_dim !== 'height')
Derek Allard2067d1a2008-11-13 22:59:24 +00001416 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001417 if ($this->width > 0 && $this->height > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001418 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001419 $this->master_dim = ((($this->orig_height/$this->orig_width) - ($this->height/$this->width)) < 0)
1420 ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001421 }
1422 else
1423 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001424 $this->master_dim = ($this->height === 0) ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001425 }
1426 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001427 elseif (($this->master_dim === 'width' && $this->width === 0)
1428 OR ($this->master_dim === 'height' && $this->height === 0))
1429 {
1430 return;
1431 }
1432
1433 if ($this->master_dim === 'width')
1434 {
1435 $this->height = (int) ceil($this->width*$this->orig_height/$this->orig_width);
1436 }
1437 else
1438 {
1439 $this->width = (int) ceil($this->orig_width*$this->height/$this->orig_height);
1440 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001441 }
1442
1443 // --------------------------------------------------------------------
1444
1445 /**
1446 * Get image properties
1447 *
1448 * A helper function that gets info about the file
1449 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001450 * @param string
1451 * @return mixed
1452 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001453 public function get_image_properties($path = '', $return = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001454 {
1455 // For now we require GD but we should
1456 // find a way to determine this using IM or NetPBM
1457
1458 if ($path == '')
Andrey Andreev8e70b792012-01-12 20:19:24 +02001459 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001460 $path = $this->full_src_path;
Andrey Andreev8e70b792012-01-12 20:19:24 +02001461 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001462
1463 if ( ! file_exists($path))
1464 {
1465 $this->set_error('imglib_invalid_path');
1466 return FALSE;
1467 }
1468
Phil Sturgeon901998a2011-08-26 10:03:33 +01001469 $vals = getimagesize($path);
Derek Allard2067d1a2008-11-13 22:59:24 +00001470 $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
Andrey Andreeva92b9032011-12-24 19:05:58 +02001471 $mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001472
1473 if ($return == TRUE)
1474 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001475 return array(
1476 'width' => $vals[0],
1477 'height' => $vals[1],
1478 'image_type' => $vals[2],
1479 'size_str' => $vals[3],
1480 'mime_type' => $mime
1481 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001482 }
1483
Andrey Andreeva92b9032011-12-24 19:05:58 +02001484 $this->orig_width = $vals[0];
1485 $this->orig_height = $vals[1];
1486 $this->image_type = $vals[2];
1487 $this->size_str = $vals[3];
Derek Allard2067d1a2008-11-13 22:59:24 +00001488 $this->mime_type = $mime;
1489
1490 return TRUE;
1491 }
1492
1493 // --------------------------------------------------------------------
1494
1495 /**
1496 * Size calculator
1497 *
1498 * This function takes a known width x height and
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001499 * recalculates it to a new size. Only one
Derek Allard2067d1a2008-11-13 22:59:24 +00001500 * new variable needs to be known
1501 *
1502 * $props = array(
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001503 * 'width' => $width,
1504 * 'height' => $height,
1505 * 'new_width' => 40,
1506 * 'new_height' => ''
1507 * );
Derek Allard2067d1a2008-11-13 22:59:24 +00001508 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001509 * @param array
1510 * @return array
1511 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001512 public function size_calculator($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001513 {
1514 if ( ! is_array($vals))
1515 {
1516 return;
1517 }
1518
1519 $allowed = array('new_width', 'new_height', 'width', 'height');
1520
1521 foreach ($allowed as $item)
1522 {
1523 if ( ! isset($vals[$item]) OR $vals[$item] == '')
1524 $vals[$item] = 0;
1525 }
1526
1527 if ($vals['width'] == 0 OR $vals['height'] == 0)
1528 {
1529 return $vals;
1530 }
1531
1532 if ($vals['new_width'] == 0)
1533 {
1534 $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1535 }
1536 elseif ($vals['new_height'] == 0)
1537 {
1538 $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1539 }
1540
1541 return $vals;
1542 }
1543
1544 // --------------------------------------------------------------------
1545
1546 /**
1547 * Explode source_image
1548 *
1549 * This is a helper function that extracts the extension
Derek Jones4b9c6292011-07-01 17:40:48 -05001550 * from the source_image. This function lets us deal with
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001551 * source_images with multiple periods, like: my.cool.jpg
Derek Allard2067d1a2008-11-13 22:59:24 +00001552 * It returns an associative array with two elements:
Derek Jones4b9c6292011-07-01 17:40:48 -05001553 * $array['ext'] = '.jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001554 * $array['name'] = 'my.cool';
1555 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001556 * @param array
1557 * @return array
1558 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001559 public function explode_name($source_image)
Derek Allard2067d1a2008-11-13 22:59:24 +00001560 {
Derek Jones08cae632009-02-10 20:03:29 +00001561 $ext = strrchr($source_image, '.');
1562 $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
Barry Mienydd671972010-10-04 16:33:58 +02001563
Derek Jones08cae632009-02-10 20:03:29 +00001564 return array('ext' => $ext, 'name' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001565 }
1566
1567 // --------------------------------------------------------------------
1568
1569 /**
1570 * Is GD Installed?
1571 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001572 * @return bool
1573 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001574 public function gd_loaded()
Derek Allard2067d1a2008-11-13 22:59:24 +00001575 {
1576 if ( ! extension_loaded('gd'))
1577 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001578 /* As it is stated in the PHP manual, dl() is not always available
1579 * and even if so - it could generate an E_WARNING message on failure
1580 */
Andrey Andreev8e70b792012-01-12 20:19:24 +02001581 return (function_exists('dl') && @dl('gd.so'));
Derek Allard2067d1a2008-11-13 22:59:24 +00001582 }
1583
1584 return TRUE;
1585 }
1586
1587 // --------------------------------------------------------------------
1588
1589 /**
1590 * Get GD version
1591 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001592 * @return mixed
1593 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001594 public function gd_version()
Derek Allard2067d1a2008-11-13 22:59:24 +00001595 {
1596 if (function_exists('gd_info'))
1597 {
1598 $gd_version = @gd_info();
Andrey Andreev8e70b792012-01-12 20:19:24 +02001599 return preg_replace('/\D/', '', $gd_version['GD Version']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001600 }
1601
1602 return FALSE;
1603 }
1604
1605 // --------------------------------------------------------------------
1606
1607 /**
1608 * Set error message
1609 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001610 * @param string
1611 * @return void
1612 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001613 public function set_error($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +00001614 {
1615 $CI =& get_instance();
1616 $CI->lang->load('imglib');
1617
1618 if (is_array($msg))
1619 {
1620 foreach ($msg as $val)
1621 {
1622
1623 $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
1624 $this->error_msg[] = $msg;
1625 log_message('error', $msg);
1626 }
1627 }
1628 else
1629 {
1630 $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
1631 $this->error_msg[] = $msg;
1632 log_message('error', $msg);
1633 }
1634 }
1635
1636 // --------------------------------------------------------------------
1637
1638 /**
1639 * Show error messages
1640 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001641 * @param string
1642 * @return string
1643 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001644 public function display_errors($open = '<p>', $close = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +00001645 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001646 return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001647 }
1648
1649}
Derek Allard2067d1a2008-11-13 22:59:24 +00001650
1651/* End of file Image_lib.php */
Andrey Andreev1b815532012-04-03 16:06:03 +03001652/* Location: ./system/libraries/Image_lib.php */