blob: b89bc5b7e37caff8f82a281ef155a410ecfcd5b2 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Eric Barnesb1673362011-12-05 22:05:38 -05008 *
Instructor, BCIT0e59db62019-01-01 08:34:36 -08009 * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
Eric Barnesb1673362011-12-05 22:05:38 -050010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
Andrey Andreev1924e872016-01-11 12:55:34 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
Instructor, BCIT0e59db62019-01-01 08:34:36 -080032 * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
33 * @license https://opensource.org/licenses/MIT MIT License
Andrey Andreevbd202c92016-01-11 12:50:18 +020034 * @link https://codeigniter.com
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020035 * @since Version 1.0.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * Image Manipulation class
42 *
43 * @package CodeIgniter
44 * @subpackage Libraries
45 * @category Image_lib
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Andrey Andreevbd202c92016-01-11 12:50:18 +020047 * @link https://codeigniter.com/user_guide/libraries/image_lib.html
Derek Allard2067d1a2008-11-13 22:59:24 +000048 */
49class CI_Image_lib {
50
Timothy Warrenb8e62852012-04-26 18:40:54 -040051 /**
52 * PHP extension/library to use for image manipulation
Andrey Andreev56454792012-05-17 14:32:19 +030053 * Can be: imagemagick, netpbm, gd, gd2
Timothy Warrenb8e62852012-04-26 18:40:54 -040054 *
55 * @var string
56 */
57 public $image_library = 'gd2';
Andrey Andreev56454792012-05-17 14:32:19 +030058
Timothy Warrenb8e62852012-04-26 18:40:54 -040059 /**
60 * Path to the graphic library (if applicable)
61 *
62 * @var string
63 */
Andrey Andreev3a459572011-12-21 11:23:11 +020064 public $library_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +030065
Timothy Warrenb8e62852012-04-26 18:40:54 -040066 /**
67 * Whether to send to browser or write to disk
68 *
69 * @var bool
70 */
71 public $dynamic_output = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +030072
Timothy Warrenb8e62852012-04-26 18:40:54 -040073 /**
74 * Path to original image
75 *
76 * @var string
77 */
Andrey Andreev3a459572011-12-21 11:23:11 +020078 public $source_image = '';
Andrey Andreev56454792012-05-17 14:32:19 +030079
Timothy Warrenb8e62852012-04-26 18:40:54 -040080 /**
81 * Path to the modified image
82 *
83 * @var string
84 */
Andrey Andreev56454792012-05-17 14:32:19 +030085 public $new_image = '';
86
Timothy Warrenb8e62852012-04-26 18:40:54 -040087 /**
88 * Image width
89 *
90 * @var int
91 */
Andrey Andreev56454792012-05-17 14:32:19 +030092 public $width = '';
93
Timothy Warrenb8e62852012-04-26 18:40:54 -040094 /**
95 * Image height
96 *
97 * @var int
98 */
Andrey Andreev56454792012-05-17 14:32:19 +030099 public $height = '';
100
Timothy Warrenb8e62852012-04-26 18:40:54 -0400101 /**
102 * Quality percentage of new image
103 *
104 * @var int
105 */
Andrey Andreev56454792012-05-17 14:32:19 +0300106 public $quality = 90;
107
Timothy Warrenb8e62852012-04-26 18:40:54 -0400108 /**
109 * Whether to create a thumbnail
110 *
111 * @var bool
112 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200113 public $create_thumb = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300114
Timothy Warrenb8e62852012-04-26 18:40:54 -0400115 /**
116 * String to add to thumbnail version of image
117 *
118 * @var string
119 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200120 public $thumb_marker = '_thumb';
Andrey Andreev56454792012-05-17 14:32:19 +0300121
Timothy Warrenb8e62852012-04-26 18:40:54 -0400122 /**
123 * Whether to maintain aspect ratio when resizing or use hard values
124 *
125 * @var bool
126 */
127 public $maintain_ratio = TRUE;
Andrey Andreev56454792012-05-17 14:32:19 +0300128
Timothy Warrenb8e62852012-04-26 18:40:54 -0400129 /**
130 * auto, height, or width. Determines what to use as the master dimension
131 *
132 * @var string
133 */
Andrey Andreev56454792012-05-17 14:32:19 +0300134 public $master_dim = 'auto';
135
Timothy Warrenb8e62852012-04-26 18:40:54 -0400136 /**
137 * Angle at to rotate image
138 *
139 * @var string
140 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200141 public $rotation_angle = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300142
Timothy Warrenb8e62852012-04-26 18:40:54 -0400143 /**
144 * X Coordinate for manipulation of the current image
145 *
146 * @var int
147 */
Andrey Andreev56454792012-05-17 14:32:19 +0300148 public $x_axis = '';
149
Timothy Warrenb8e62852012-04-26 18:40:54 -0400150 /**
151 * Y Coordinate for manipulation of the current image
152 *
153 * @var int
154 */
Andrey Andreev56454792012-05-17 14:32:19 +0300155 public $y_axis = '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000156
Timothy Warrenb8e62852012-04-26 18:40:54 -0400157 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000158 // Watermark Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400159 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +0300160
Timothy Warrenb8e62852012-04-26 18:40:54 -0400161 /**
162 * Watermark text if graphic is not used
163 *
164 * @var string
165 */
166 public $wm_text = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300167
Timothy Warrenb8e62852012-04-26 18:40:54 -0400168 /**
169 * Type of watermarking. Options: text/overlay
170 *
171 * @var string
172 */
173 public $wm_type = 'text';
Andrey Andreev56454792012-05-17 14:32:19 +0300174
Timothy Warrenb8e62852012-04-26 18:40:54 -0400175 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400176 * Default transparency for watermark
Andrey Andreev56454792012-05-17 14:32:19 +0300177 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400178 * @var int
179 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200180 public $wm_x_transp = 4;
Andrey Andreev56454792012-05-17 14:32:19 +0300181
Timothy Warrenb8e62852012-04-26 18:40:54 -0400182 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400183 * Default transparency for watermark
184 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400185 * @var int
186 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200187 public $wm_y_transp = 4;
Andrey Andreev56454792012-05-17 14:32:19 +0300188
Timothy Warrenb8e62852012-04-26 18:40:54 -0400189 /**
190 * Watermark image path
Andrey Andreev56454792012-05-17 14:32:19 +0300191 *
Timothy Warrenb8e62852012-04-26 18:40:54 -0400192 * @var string
193 */
Andrey Andreev56454792012-05-17 14:32:19 +0300194 public $wm_overlay_path = '';
195
Timothy Warrenb8e62852012-04-26 18:40:54 -0400196 /**
197 * TT font
198 *
199 * @var string
200 */
201 public $wm_font_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300202
Timothy Warrenb8e62852012-04-26 18:40:54 -0400203 /**
204 * Font size (different versions of GD will either use points or pixels)
205 *
206 * @var int
207 */
208 public $wm_font_size = 17;
Andrey Andreev56454792012-05-17 14:32:19 +0300209
Timothy Warrenb8e62852012-04-26 18:40:54 -0400210 /**
211 * Vertical alignment: T M B
212 *
213 * @var string
214 */
215 public $wm_vrt_alignment = 'B';
Andrey Andreev56454792012-05-17 14:32:19 +0300216
Timothy Warrenb8e62852012-04-26 18:40:54 -0400217 /**
218 * Horizontal alignment: L R C
219 *
220 * @var string
221 */
222 public $wm_hor_alignment = 'C';
Andrey Andreev56454792012-05-17 14:32:19 +0300223
Timothy Warrenb8e62852012-04-26 18:40:54 -0400224 /**
225 * Padding around text
226 *
227 * @var int
228 */
229 public $wm_padding = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300230
Timothy Warrenb8e62852012-04-26 18:40:54 -0400231 /**
232 * Lets you push text to the right
233 *
234 * @var int
235 */
236 public $wm_hor_offset = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300237
Timothy Warrenb8e62852012-04-26 18:40:54 -0400238 /**
239 * Lets you push text down
240 *
241 * @var int
242 */
243 public $wm_vrt_offset = 0;
Andrey Andreev56454792012-05-17 14:32:19 +0300244
Timothy Warrenb8e62852012-04-26 18:40:54 -0400245 /**
246 * Text color
247 *
248 * @var string
249 */
Andrey Andreev56454792012-05-17 14:32:19 +0300250 protected $wm_font_color = '#ffffff';
251
Timothy Warrenb8e62852012-04-26 18:40:54 -0400252 /**
253 * Dropshadow color
254 *
255 * @var string
256 */
Andrey Andreev56454792012-05-17 14:32:19 +0300257 protected $wm_shadow_color = '';
258
Timothy Warrenb8e62852012-04-26 18:40:54 -0400259 /**
260 * Dropshadow distance
261 *
262 * @var int
263 */
264 public $wm_shadow_distance = 2;
Andrey Andreev56454792012-05-17 14:32:19 +0300265
Timothy Warrenb8e62852012-04-26 18:40:54 -0400266 /**
267 * Image opacity: 1 - 100 Only works with image
268 *
269 * @var int
270 */
Andrey Andreev56454792012-05-17 14:32:19 +0300271 public $wm_opacity = 50;
Derek Allard2067d1a2008-11-13 22:59:24 +0000272
Timothy Warrenb8e62852012-04-26 18:40:54 -0400273 // --------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 // Private Vars
Timothy Warrenb8e62852012-04-26 18:40:54 -0400275 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +0300276
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400277 /**
278 * Source image folder
279 *
280 * @var string
281 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200282 public $source_folder = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300283
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400284 /**
285 * Destination image folder
286 *
287 * @var string
288 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200289 public $dest_folder = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300290
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400291 /**
292 * Image mime-type
293 *
294 * @var string
295 */
Andrey Andreev56454792012-05-17 14:32:19 +0300296 public $mime_type = '';
297
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400298 /**
Andrey Andreev56454792012-05-17 14:32:19 +0300299 * Original image width
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400300 *
301 * @var int
302 */
Andrey Andreev56454792012-05-17 14:32:19 +0300303 public $orig_width = '';
304
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400305 /**
306 * Original image height
307 *
308 * @var int
309 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200310 public $orig_height = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300311
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400312 /**
313 * Image format
Andrey Andreev56454792012-05-17 14:32:19 +0300314 *
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400315 * @var string
316 */
Andrey Andreev56454792012-05-17 14:32:19 +0300317 public $image_type = '';
318
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400319 /**
320 * Size of current image
321 *
322 * @var string
323 */
Andrey Andreev56454792012-05-17 14:32:19 +0300324 public $size_str = '';
325
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400326 /**
327 * Full path to source image
328 *
329 * @var string
330 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200331 public $full_src_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300332
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400333 /**
334 * Full path to destination image
335 *
336 * @var string
337 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200338 public $full_dst_path = '';
Andrey Andreev56454792012-05-17 14:32:19 +0300339
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400340 /**
Andrey Andreev45965742014-08-27 20:40:11 +0300341 * File permissions
342 *
343 * @var int
344 */
345 public $file_permissions = 0644;
346
347 /**
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400348 * Name of function to create image
349 *
350 * @var string
351 */
Andrey Andreev56454792012-05-17 14:32:19 +0300352 public $create_fnc = 'imagecreatetruecolor';
353
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400354 /**
355 * Name of function to copy image
356 *
357 * @var string
358 */
Andrey Andreev56454792012-05-17 14:32:19 +0300359 public $copy_fnc = 'imagecopyresampled';
360
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400361 /**
362 * Error messages
363 *
364 * @var array
365 */
Andrey Andreev56454792012-05-17 14:32:19 +0300366 public $error_msg = array();
367
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400368 /**
369 * Whether to have a drop shadow on watermark
370 *
371 * @var bool
372 */
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200373 protected $wm_use_drop_shadow = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300374
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400375 /**
376 * Whether to use truetype fonts
377 *
378 * @var bool
379 */
Andrey Andreev3a459572011-12-21 11:23:11 +0200380 public $wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000381
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400382 /**
383 * Initialize Image Library
384 *
385 * @param array $props
Andrey Andreev56454792012-05-17 14:32:19 +0300386 * @return void
Timothy Warrenb82bc3a2012-04-27 09:12:58 -0400387 */
Greg Akera9263282010-11-10 15:26:43 -0600388 public function __construct($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000389 {
390 if (count($props) > 0)
391 {
392 $this->initialize($props);
393 }
394
Andrey Andreev8f9ab652017-01-10 12:30:38 +0200395 /**
396 * A work-around for some improperly formatted, but
397 * usable JPEGs; known to be produced by Samsung
398 * smartphones' front-facing cameras.
399 *
400 * @see https://github.com/bcit-ci/CodeIgniter/issues/4967
401 * @see https://bugs.php.net/bug.php?id=72404
402 */
403 ini_set('gd.jpeg_ignore_warning', 1);
404
Andrey Andreev90726b82015-01-20 12:39:22 +0200405 log_message('info', 'Image Lib Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 }
407
408 // --------------------------------------------------------------------
409
410 /**
411 * Initialize image properties
412 *
413 * Resets values in case this class is used in a loop
414 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000415 * @return void
416 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200417 public function clear()
Derek Allard2067d1a2008-11-13 22:59:24 +0000418 {
Sam Doidge5cb5c0a2013-03-13 01:28:06 +0000419 $props = array('thumb_marker', '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 +0000420
421 foreach ($props as $val)
422 {
423 $this->$val = '';
424 }
425
Michael Denniscb07a322011-08-20 23:40:59 -0700426 $this->image_library = 'gd2';
427 $this->dynamic_output = FALSE;
Andrey Andreev56454792012-05-17 14:32:19 +0300428 $this->quality = 90;
Michael Denniscb07a322011-08-20 23:40:59 -0700429 $this->create_thumb = FALSE;
430 $this->thumb_marker = '_thumb';
431 $this->maintain_ratio = TRUE;
432 $this->master_dim = 'auto';
433 $this->wm_type = 'text';
434 $this->wm_x_transp = 4;
435 $this->wm_y_transp = 4;
436 $this->wm_font_size = 17;
437 $this->wm_vrt_alignment = 'B';
438 $this->wm_hor_alignment = 'C';
439 $this->wm_padding = 0;
440 $this->wm_hor_offset = 0;
441 $this->wm_vrt_offset = 0;
442 $this->wm_font_color = '#ffffff';
443 $this->wm_shadow_distance = 2;
444 $this->wm_opacity = 50;
445 $this->create_fnc = 'imagecreatetruecolor';
446 $this->copy_fnc = 'imagecopyresampled';
447 $this->error_msg = array();
448 $this->wm_use_drop_shadow = FALSE;
449 $this->wm_use_truetype = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 }
451
452 // --------------------------------------------------------------------
453
454 /**
455 * initialize image preferences
456 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000457 * @param array
458 * @return bool
459 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200460 public function initialize($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200462 // Convert array elements into class variables
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 if (count($props) > 0)
464 {
465 foreach ($props as $key => $val)
466 {
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200467 if (property_exists($this, $key))
468 {
Andrey Andreeveac4adf2016-03-22 11:24:14 +0200469 if (in_array($key, array('wm_font_color', 'wm_shadow_color'), TRUE))
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200470 {
Andrey Andreev8323ae62011-12-31 18:39:10 +0200471 if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200472 {
Andrey Andreevcf2ba9e2012-01-01 21:57:13 +0200473 /* $matches[1] contains our hex color value, but it might be
Andrey Andreev8323ae62011-12-31 18:39:10 +0200474 * both in the full 6-length format or the shortened 3-length
475 * value.
Andrey Andreevbb96c8b2011-12-31 18:48:39 +0200476 * We'll later need the full version, so we keep it if it's
Andrey Andreev8323ae62011-12-31 18:39:10 +0200477 * already there and if not - we'll convert to it. We can
478 * access string characters by their index as in an array,
479 * so we'll do that and use concatenation to form the final
480 * value:
481 */
Andrey Andreev665af0c2011-12-30 14:39:29 +0200482 $val = (strlen($matches[1]) === 6)
483 ? '#'.$matches[1]
484 : '#'.$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 +0200485 }
486 else
487 {
488 continue;
489 }
490 }
Andrey Andreeveac4adf2016-03-22 11:24:14 +0200491 elseif (in_array($key, array('width', 'height'), TRUE) && ! ctype_digit((string) $val))
492 {
493 continue;
494 }
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200495
496 $this->$key = $val;
497 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000498 }
499 }
500
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200501 // Is there a source image? If not, there's no reason to continue
Alex Bilbied261b1e2012-06-02 11:12:16 +0100502 if ($this->source_image === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000503 {
504 $this->set_error('imglib_source_image_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500505 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 }
507
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200508 /* Is getimagesize() available?
Derek Allard2067d1a2008-11-13 22:59:24 +0000509 *
510 * We use it to determine the image properties (width/height).
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200511 * Note: We need to figure out how to determine image
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 * properties using ImageMagick and NetPBM
Derek Allard2067d1a2008-11-13 22:59:24 +0000513 */
514 if ( ! function_exists('getimagesize'))
515 {
516 $this->set_error('imglib_gd_required_for_props');
517 return FALSE;
518 }
519
520 $this->image_library = strtolower($this->image_library);
521
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200522 /* Set the full server path
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 *
524 * The source image may or may not contain a path.
525 * Either way, we'll try use realpath to generate the
526 * full server path in order to more reliably read it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 */
Andrey Andreevea41c8a2014-02-26 18:31:02 +0200528 if (($full_source_path = realpath($this->source_image)) !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000529 {
Andrey Andreevea41c8a2014-02-26 18:31:02 +0200530 $full_source_path = str_replace('\\', '/', $full_source_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000531 }
532 else
533 {
534 $full_source_path = $this->source_image;
535 }
536
537 $x = explode('/', $full_source_path);
538 $this->source_image = end($x);
539 $this->source_folder = str_replace($this->source_image, '', $full_source_path);
540
541 // Set the Image Properties
542 if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
543 {
Eric Barnesb1673362011-12-05 22:05:38 -0500544 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000545 }
546
547 /*
548 * Assign the "new" image name/path
549 *
550 * If the user has set a "new_image" name it means
551 * we are making a copy of the source image. If not
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200552 * it means we are altering the original. We'll
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 * set the destination filename and path accordingly.
Derek Allard2067d1a2008-11-13 22:59:24 +0000554 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100555 if ($this->new_image === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000556 {
Andrey Andreev961271d2016-12-09 12:48:57 +0200557 $this->dest_image = $this->source_image;
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 $this->dest_folder = $this->source_folder;
559 }
Andrey Andreev961271d2016-12-09 12:48:57 +0200560 elseif (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200561 {
Andrey Andreev961271d2016-12-09 12:48:57 +0200562 $this->dest_image = $this->new_image;
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200563 $this->dest_folder = $this->source_folder;
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200564 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000565 else
566 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200567 // Is there a file name?
Andrey Andreevf2a613d2016-12-12 11:39:38 +0200568 if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $this->new_image))
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200569 {
Andrey Andreev961271d2016-12-09 12:48:57 +0200570 $this->dest_image = $this->source_image;
Andrey Andreevf2a613d2016-12-12 11:39:38 +0200571 $this->dest_folder = $this->new_image;
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200572 }
573 else
574 {
Andrey Andreevf2a613d2016-12-12 11:39:38 +0200575 $x = explode('/', str_replace('\\', '/', $this->new_image));
Andrey Andreev961271d2016-12-09 12:48:57 +0200576 $this->dest_image = end($x);
Andrey Andreevf2a613d2016-12-12 11:39:38 +0200577 $this->dest_folder = str_replace($this->dest_image, '', $this->new_image);
Derek Allard2067d1a2008-11-13 22:59:24 +0000578 }
Andrey Andreevf2a613d2016-12-12 11:39:38 +0200579
580 $this->dest_folder = realpath($this->dest_folder).'/';
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 }
582
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200583 /* Compile the finalized filenames/paths
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 *
585 * We'll create two master strings containing the
586 * full server path to the source image and the
587 * full server path to the destination image.
588 * We'll also split the destination image name
589 * so we can insert the thumbnail marker if needed.
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100591 if ($this->create_thumb === FALSE OR $this->thumb_marker === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000592 {
593 $this->thumb_marker = '';
594 }
595
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200596 $xp = $this->explode_name($this->dest_image);
Derek Allard2067d1a2008-11-13 22:59:24 +0000597
598 $filename = $xp['name'];
599 $file_ext = $xp['ext'];
600
601 $this->full_src_path = $this->source_folder.$this->source_image;
602 $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
603
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200604 /* Should we maintain image proportions?
Derek Allard2067d1a2008-11-13 22:59:24 +0000605 *
606 * When creating thumbs or copies, the target width/height
607 * might not be in correct proportion with the source
Andrey Andreev8e70b792012-01-12 20:19:24 +0200608 * image's width/height. We'll recalculate it here.
Derek Allard2067d1a2008-11-13 22:59:24 +0000609 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100610 if ($this->maintain_ratio === TRUE && ($this->width !== 0 OR $this->height !== 0))
Derek Allard2067d1a2008-11-13 22:59:24 +0000611 {
612 $this->image_reproportion();
613 }
614
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200615 /* Was a width and height specified?
Derek Allard2067d1a2008-11-13 22:59:24 +0000616 *
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200617 * If the destination width/height was not submitted we
618 * will use the values from the actual file
Derek Allard2067d1a2008-11-13 22:59:24 +0000619 */
Alex Bilbied261b1e2012-06-02 11:12:16 +0100620 if ($this->width === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200621 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 $this->width = $this->orig_width;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200623 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000624
Alex Bilbied261b1e2012-06-02 11:12:16 +0100625 if ($this->height === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +0200626 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000627 $this->height = $this->orig_height;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200628 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000629
630 // Set the quality
Andrey Andreev8e70b792012-01-12 20:19:24 +0200631 $this->quality = trim(str_replace('%', '', $this->quality));
Derek Allard2067d1a2008-11-13 22:59:24 +0000632
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200633 if ($this->quality === '' OR $this->quality === 0 OR ! ctype_digit($this->quality))
Andrey Andreev8e70b792012-01-12 20:19:24 +0200634 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000635 $this->quality = 90;
Andrey Andreev8e70b792012-01-12 20:19:24 +0200636 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000637
638 // Set the x/y coordinates
Andrey Andreev5036c9c2012-06-04 15:34:56 +0300639 is_numeric($this->x_axis) OR $this->x_axis = 0;
640 is_numeric($this->y_axis) OR $this->y_axis = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +0000641
642 // Watermark-related Stuff...
Alex Bilbied261b1e2012-06-02 11:12:16 +0100643 if ($this->wm_overlay_path !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000644 {
Andrey Andreev8e70b792012-01-12 20:19:24 +0200645 $this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
Derek Allard2067d1a2008-11-13 22:59:24 +0000646 }
647
Alex Bilbied261b1e2012-06-02 11:12:16 +0100648 if ($this->wm_shadow_color !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000649 {
650 $this->wm_use_drop_shadow = TRUE;
651 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100652 elseif ($this->wm_use_drop_shadow === TRUE && $this->wm_shadow_color === '')
Andrey Andreev64dbdfb2011-12-30 14:14:07 +0200653 {
654 $this->wm_use_drop_shadow = FALSE;
655 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000656
Alex Bilbied261b1e2012-06-02 11:12:16 +0100657 if ($this->wm_font_path !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000658 {
659 $this->wm_use_truetype = TRUE;
660 }
661
662 return TRUE;
663 }
664
665 // --------------------------------------------------------------------
666
667 /**
668 * Image Resize
669 *
670 * This is a wrapper function that chooses the proper
671 * resize function based on the protocol specified
672 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000673 * @return bool
674 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200675 public function resize()
Derek Allard2067d1a2008-11-13 22:59:24 +0000676 {
Andrey Andreev1a9f52c2012-01-07 01:06:34 +0200677 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000678 return $this->$protocol('resize');
679 }
680
681 // --------------------------------------------------------------------
682
683 /**
684 * Image Crop
685 *
686 * This is a wrapper function that chooses the proper
687 * cropping function based on the protocol specified
688 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000689 * @return bool
690 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200691 public function crop()
Derek Allard2067d1a2008-11-13 22:59:24 +0000692 {
Andrey Andreev5a67e3d2012-01-07 01:21:09 +0200693 $protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000694 return $this->$protocol('crop');
695 }
696
697 // --------------------------------------------------------------------
698
699 /**
700 * Image Rotate
701 *
702 * This is a wrapper function that chooses the proper
703 * rotation function based on the protocol specified
704 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000705 * @return bool
706 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200707 public function rotate()
Derek Allard2067d1a2008-11-13 22:59:24 +0000708 {
709 // Allowed rotation values
710 $degs = array(90, 180, 270, 'vrt', 'hor');
711
Alex Bilbied261b1e2012-06-02 11:12:16 +0100712 if ($this->rotation_angle === '' OR ! in_array($this->rotation_angle, $degs))
Derek Allard2067d1a2008-11-13 22:59:24 +0000713 {
714 $this->set_error('imglib_rotation_angle_required');
Eric Barnesb1673362011-12-05 22:05:38 -0500715 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000716 }
717
718 // Reassign the width and height
Alex Bilbied261b1e2012-06-02 11:12:16 +0100719 if ($this->rotation_angle === 90 OR $this->rotation_angle === 270)
Derek Allard2067d1a2008-11-13 22:59:24 +0000720 {
721 $this->width = $this->orig_height;
722 $this->height = $this->orig_width;
723 }
724 else
725 {
726 $this->width = $this->orig_width;
727 $this->height = $this->orig_height;
728 }
729
Derek Allard2067d1a2008-11-13 22:59:24 +0000730 // Choose resizing function
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200731 if ($this->image_library === 'imagemagick' OR $this->image_library === 'netpbm')
Derek Allard2067d1a2008-11-13 22:59:24 +0000732 {
733 $protocol = 'image_process_'.$this->image_library;
Derek Allard2067d1a2008-11-13 22:59:24 +0000734 return $this->$protocol('rotate');
735 }
736
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200737 return ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
738 ? $this->image_mirror_gd()
739 : $this->image_rotate_gd();
Derek Allard2067d1a2008-11-13 22:59:24 +0000740 }
741
742 // --------------------------------------------------------------------
743
744 /**
745 * Image Process Using GD/GD2
746 *
747 * This function will resize or crop
748 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000749 * @param string
750 * @return bool
751 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200752 public function image_process_gd($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000753 {
754 $v2_override = FALSE;
755
756 // If the target width/height match the source, AND if the new file name is not equal to the old file name
757 // 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 +0100758 if ($this->dynamic_output === FALSE && $this->orig_width === $this->width && $this->orig_height === $this->height)
Derek Allard2067d1a2008-11-13 22:59:24 +0000759 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100760 if ($this->source_image !== $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000761 {
Andrey Andreev45965742014-08-27 20:40:11 +0300762 chmod($this->full_dst_path, $this->file_permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +0000763 }
Andrey Andreeva92b9032011-12-24 19:05:58 +0200764
765 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000766 }
767
768 // Let's set up our values based on the action
Alex Bilbied261b1e2012-06-02 11:12:16 +0100769 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000770 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200771 // Reassign the source width/height if cropping
Derek Jones4b9c6292011-07-01 17:40:48 -0500772 $this->orig_width = $this->width;
Derek Allard2067d1a2008-11-13 22:59:24 +0000773 $this->orig_height = $this->height;
774
775 // GD 2.0 has a cropping bug so we'll test for it
776 if ($this->gd_version() !== FALSE)
777 {
778 $gd_version = str_replace('0', '', $this->gd_version());
Andrey Andreevd4818b72014-10-23 17:15:32 +0300779 $v2_override = ($gd_version == 2);
Derek Allard2067d1a2008-11-13 22:59:24 +0000780 }
781 }
782 else
783 {
784 // If resizing the x/y axis must be zero
785 $this->x_axis = 0;
786 $this->y_axis = 0;
787 }
788
Andrey Andreev10fb7d12015-08-03 10:05:29 +0300789 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +0000790 if ( ! ($src_img = $this->image_create_gd()))
791 {
792 return FALSE;
793 }
794
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200795 /* Create the image
796 *
797 * Old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
798 * it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
799 * below should that ever prove inaccurate.
800 *
Alex Bilbied261b1e2012-06-02 11:12:16 +0100801 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override === FALSE)
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200802 */
Andrey Andreev8e70b792012-01-12 20:19:24 +0200803 if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000804 {
805 $create = 'imagecreatetruecolor';
806 $copy = 'imagecopyresampled';
807 }
808 else
809 {
810 $create = 'imagecreate';
811 $copy = 'imagecopyresized';
812 }
813
814 $dst_img = $create($this->width, $this->height);
Derek Jones595bfd12010-08-20 10:28:22 -0500815
Alex Bilbied261b1e2012-06-02 11:12:16 +0100816 if ($this->image_type === 3) // png we can actually preserve transparency
Derek Jones595bfd12010-08-20 10:28:22 -0500817 {
818 imagealphablending($dst_img, FALSE);
819 imagesavealpha($dst_img, TRUE);
820 }
Barry Mienydd671972010-10-04 16:33:58 +0200821
Derek Allard2067d1a2008-11-13 22:59:24 +0000822 $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
823
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200824 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +0100825 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000826 {
827 $this->image_display_gd($dst_img);
828 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200829 elseif ( ! $this->image_save_gd($dst_img)) // Or save it
Derek Allard2067d1a2008-11-13 22:59:24 +0000830 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200831 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000832 }
833
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200834 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +0000835 imagedestroy($dst_img);
836 imagedestroy($src_img);
837
Andrey Andreev0768a402018-03-10 02:08:32 +0200838 if ($this->dynamic_output !== TRUE)
839 {
840 chmod($this->full_dst_path, $this->file_permissions);
841 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000842
843 return TRUE;
844 }
845
846 // --------------------------------------------------------------------
847
848 /**
849 * Image Process Using ImageMagick
850 *
851 * This function will resize, crop or rotate
852 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000853 * @param string
854 * @return bool
855 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200856 public function image_process_imagemagick($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000857 {
Andrey Andreev3a197592015-05-21 01:05:06 +0300858 // Do we have a vaild library path?
Alex Bilbied261b1e2012-06-02 11:12:16 +0100859 if ($this->library_path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000860 {
861 $this->set_error('imglib_libpath_invalid');
862 return FALSE;
863 }
864
Andrey Andreev8e70b792012-01-12 20:19:24 +0200865 if ( ! preg_match('/convert$/i', $this->library_path))
Derek Allard2067d1a2008-11-13 22:59:24 +0000866 {
Andrey Andreeva92b9032011-12-24 19:05:58 +0200867 $this->library_path = rtrim($this->library_path, '/').'/convert';
Derek Allard2067d1a2008-11-13 22:59:24 +0000868 }
869
870 // Execute the command
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200871 $cmd = $this->library_path.' -quality '.$this->quality;
Derek Allard2067d1a2008-11-13 22:59:24 +0000872
Alex Bilbied261b1e2012-06-02 11:12:16 +0100873 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000874 {
Andrey Andreevb3f69342016-03-22 11:31:58 +0200875 $cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis;
Derek Allard2067d1a2008-11-13 22:59:24 +0000876 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100877 elseif ($action === 'rotate')
Derek Allard2067d1a2008-11-13 22:59:24 +0000878 {
Andrey Andreevb3f69342016-03-22 11:31:58 +0200879 $cmd .= ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
880 ? ' -flop'
881 : ' -rotate '.$this->rotation_angle;
Derek Allard2067d1a2008-11-13 22:59:24 +0000882 }
Andrey Andreev8e70b792012-01-12 20:19:24 +0200883 else // Resize
Derek Allard2067d1a2008-11-13 22:59:24 +0000884 {
Omar24063af2012-07-02 13:50:17 -0300885 if($this->maintain_ratio === TRUE)
886 {
Andrey Andreevb3f69342016-03-22 11:31:58 +0200887 $cmd .= ' -resize '.$this->width.'x'.$this->height;
Omar24063af2012-07-02 13:50:17 -0300888 }
Omarbb531d62012-06-29 10:48:28 -0300889 else
Omar24063af2012-07-02 13:50:17 -0300890 {
Andrey Andreevb3f69342016-03-22 11:31:58 +0200891 $cmd .= ' -resize '.$this->width.'x'.$this->height.'\!';
Omar24063af2012-07-02 13:50:17 -0300892 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000893 }
894
Andrey Andreevbe8bd922016-11-07 12:31:31 +0200895 $cmd .= ' '.escapeshellarg($this->full_src_path).' '.escapeshellarg($this->full_dst_path).' 2>&1';
Andrey Andreevb3f69342016-03-22 11:31:58 +0200896
Derek Allard2067d1a2008-11-13 22:59:24 +0000897 $retval = 1;
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200898 // exec() might be disabled
899 if (function_usable('exec'))
900 {
901 @exec($cmd, $output, $retval);
902 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000903
Andrey Andreev8e70b792012-01-12 20:19:24 +0200904 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000905 if ($retval > 0)
906 {
907 $this->set_error('imglib_image_process_failed');
908 return FALSE;
909 }
910
Andrey Andreev45965742014-08-27 20:40:11 +0300911 chmod($this->full_dst_path, $this->file_permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +0000912
913 return TRUE;
914 }
915
916 // --------------------------------------------------------------------
917
918 /**
919 * Image Process Using NetPBM
920 *
921 * This function will resize, crop or rotate
922 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000923 * @param string
924 * @return bool
925 */
Andrey Andreev4eea9892011-12-19 12:05:41 +0200926 public function image_process_netpbm($action = 'resize')
Derek Allard2067d1a2008-11-13 22:59:24 +0000927 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100928 if ($this->library_path === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000929 {
930 $this->set_error('imglib_libpath_invalid');
931 return FALSE;
932 }
933
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200934 // Build the resizing command
Derek Allard2067d1a2008-11-13 22:59:24 +0000935 switch ($this->image_type)
936 {
937 case 1 :
Andrey Andreev56454792012-05-17 14:32:19 +0300938 $cmd_in = 'giftopnm';
939 $cmd_out = 'ppmtogif';
Derek Allard2067d1a2008-11-13 22:59:24 +0000940 break;
941 case 2 :
Andrey Andreev56454792012-05-17 14:32:19 +0300942 $cmd_in = 'jpegtopnm';
943 $cmd_out = 'ppmtojpeg';
Derek Allard2067d1a2008-11-13 22:59:24 +0000944 break;
945 case 3 :
Andrey Andreev56454792012-05-17 14:32:19 +0300946 $cmd_in = 'pngtopnm';
947 $cmd_out = 'ppmtopng';
Derek Allard2067d1a2008-11-13 22:59:24 +0000948 break;
949 }
950
Alex Bilbied261b1e2012-06-02 11:12:16 +0100951 if ($action === 'crop')
Derek Allard2067d1a2008-11-13 22:59:24 +0000952 {
953 $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
954 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100955 elseif ($action === 'rotate')
Derek Allard2067d1a2008-11-13 22:59:24 +0000956 {
957 switch ($this->rotation_angle)
958 {
Andrey Andreev56454792012-05-17 14:32:19 +0300959 case 90: $angle = 'r270';
Derek Allard2067d1a2008-11-13 22:59:24 +0000960 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300961 case 180: $angle = 'r180';
Derek Allard2067d1a2008-11-13 22:59:24 +0000962 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300963 case 270: $angle = 'r90';
Derek Allard2067d1a2008-11-13 22:59:24 +0000964 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300965 case 'vrt': $angle = 'tb';
Derek Allard2067d1a2008-11-13 22:59:24 +0000966 break;
Andrey Andreev56454792012-05-17 14:32:19 +0300967 case 'hor': $angle = 'lr';
Derek Allard2067d1a2008-11-13 22:59:24 +0000968 break;
969 }
970
971 $cmd_inner = 'pnmflip -'.$angle.' ';
972 }
973 else // Resize
974 {
975 $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
976 }
977
Andrey Andreev6cab7892017-07-17 13:14:00 +0300978 $cmd = $this->library_path.$cmd_in.' '.escapeshellarg($this->full_src_path).' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
Derek Allard2067d1a2008-11-13 22:59:24 +0000979
980 $retval = 1;
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200981 // exec() might be disabled
982 if (function_usable('exec'))
983 {
984 @exec($cmd, $output, $retval);
985 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000986
Andrey Andreev8e70b792012-01-12 20:19:24 +0200987 // Did it work?
Derek Allard2067d1a2008-11-13 22:59:24 +0000988 if ($retval > 0)
989 {
990 $this->set_error('imglib_image_process_failed');
991 return FALSE;
992 }
993
994 // With NetPBM we have to create a temporary image.
995 // If you try manipulating the original it fails so
996 // we have to rename the temp file.
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200997 copy($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
Andrey Andreev2c8baeb2012-01-19 15:45:28 +0200998 unlink($this->dest_folder.'netpbm.tmp');
Andrey Andreev45965742014-08-27 20:40:11 +0300999 chmod($this->full_dst_path, $this->file_permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +00001000
1001 return TRUE;
1002 }
1003
1004 // --------------------------------------------------------------------
1005
1006 /**
1007 * Image Rotate Using GD
1008 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001009 * @return bool
1010 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001011 public function image_rotate_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +00001012 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001013 // Create the image handle
Derek Allard2067d1a2008-11-13 22:59:24 +00001014 if ( ! ($src_img = $this->image_create_gd()))
1015 {
1016 return FALSE;
1017 }
1018
1019 // Set the background color
1020 // This won't work with transparent PNG files so we are
1021 // going to have to figure out how to determine the color
1022 // of the alpha channel in a future release.
1023
Andrey Andreev3a197592015-05-21 01:05:06 +03001024 $white = imagecolorallocate($src_img, 255, 255, 255);
Derek Allard2067d1a2008-11-13 22:59:24 +00001025
Andrey Andreev8e70b792012-01-12 20:19:24 +02001026 // Rotate it!
Derek Allard2067d1a2008-11-13 22:59:24 +00001027 $dst_img = imagerotate($src_img, $this->rotation_angle, $white);
1028
Andrey Andreev8e70b792012-01-12 20:19:24 +02001029 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001030 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001031 {
1032 $this->image_display_gd($dst_img);
1033 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001034 elseif ( ! $this->image_save_gd($dst_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001035 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001036 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001037 }
1038
Andrey Andreev8e70b792012-01-12 20:19:24 +02001039 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001040 imagedestroy($dst_img);
1041 imagedestroy($src_img);
1042
Andrey Andreev45965742014-08-27 20:40:11 +03001043 chmod($this->full_dst_path, $this->file_permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +00001044
Pascal Kriete8761ef52011-02-14 13:13:52 -05001045 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001046 }
1047
1048 // --------------------------------------------------------------------
1049
1050 /**
1051 * Create Mirror Image using GD
1052 *
1053 * This function will flip horizontal or vertical
1054 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001055 * @return bool
1056 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001057 public function image_mirror_gd()
Derek Allard2067d1a2008-11-13 22:59:24 +00001058 {
1059 if ( ! $src_img = $this->image_create_gd())
1060 {
1061 return FALSE;
1062 }
1063
Derek Jones4b9c6292011-07-01 17:40:48 -05001064 $width = $this->orig_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001065 $height = $this->orig_height;
1066
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001067 if ($this->rotation_angle === 'hor')
Derek Allard2067d1a2008-11-13 22:59:24 +00001068 {
Andrey Andreevfbde2792015-05-11 11:03:06 +03001069 for ($i = 0; $i < $height; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001070 {
Andrey Andreevfbde2792015-05-11 11:03:06 +03001071 $left = 0;
1072 $right = $width - 1;
1073
Derek Allard2067d1a2008-11-13 22:59:24 +00001074 while ($left < $right)
1075 {
1076 $cl = imagecolorat($src_img, $left, $i);
1077 $cr = imagecolorat($src_img, $right, $i);
1078
1079 imagesetpixel($src_img, $left, $i, $cr);
1080 imagesetpixel($src_img, $right, $i, $cl);
1081
1082 $left++;
1083 $right--;
1084 }
1085 }
1086 }
1087 else
1088 {
Andrey Andreevfbde2792015-05-11 11:03:06 +03001089 for ($i = 0; $i < $width; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001090 {
Andrey Andreevfbde2792015-05-11 11:03:06 +03001091 $top = 0;
1092 $bottom = $height - 1;
1093
Andrey Andreev5d78fd82015-05-11 18:19:01 +03001094 while ($top < $bottom)
Derek Allard2067d1a2008-11-13 22:59:24 +00001095 {
1096 $ct = imagecolorat($src_img, $i, $top);
Andrey Andreevfbde2792015-05-11 11:03:06 +03001097 $cb = imagecolorat($src_img, $i, $bottom);
Derek Allard2067d1a2008-11-13 22:59:24 +00001098
1099 imagesetpixel($src_img, $i, $top, $cb);
Andrey Andreevfbde2792015-05-11 11:03:06 +03001100 imagesetpixel($src_img, $i, $bottom, $ct);
Derek Allard2067d1a2008-11-13 22:59:24 +00001101
1102 $top++;
Andrey Andreevfbde2792015-05-11 11:03:06 +03001103 $bottom--;
Derek Allard2067d1a2008-11-13 22:59:24 +00001104 }
1105 }
1106 }
1107
Andrey Andreev8e70b792012-01-12 20:19:24 +02001108 // Show the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001109 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001110 {
1111 $this->image_display_gd($src_img);
1112 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001113 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001114 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001115 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001116 }
1117
Andrey Andreev8e70b792012-01-12 20:19:24 +02001118 // Kill the file handles
Derek Allard2067d1a2008-11-13 22:59:24 +00001119 imagedestroy($src_img);
1120
Andrey Andreev45965742014-08-27 20:40:11 +03001121 chmod($this->full_dst_path, $this->file_permissions);
Derek Allard2067d1a2008-11-13 22:59:24 +00001122
1123 return TRUE;
1124 }
1125
1126 // --------------------------------------------------------------------
1127
1128 /**
1129 * Image Watermark
1130 *
1131 * This is a wrapper function that chooses the type
1132 * of watermarking based on the specified preference.
1133 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001134 * @return bool
1135 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001136 public function watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001137 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001138 return ($this->wm_type === 'overlay') ? $this->overlay_watermark() : $this->text_watermark();
Derek Allard2067d1a2008-11-13 22:59:24 +00001139 }
1140
1141 // --------------------------------------------------------------------
1142
1143 /**
1144 * Watermark - Graphic Version
1145 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001146 * @return bool
1147 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001148 public function overlay_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001149 {
1150 if ( ! function_exists('imagecolortransparent'))
1151 {
1152 $this->set_error('imglib_gd_required');
1153 return FALSE;
1154 }
1155
Andrey Andreev8e70b792012-01-12 20:19:24 +02001156 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001157 $this->get_image_properties();
1158
Andrey Andreev8e70b792012-01-12 20:19:24 +02001159 // Fetch watermark image properties
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001160 $props = $this->get_image_properties($this->wm_overlay_path, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001161 $wm_img_type = $props['image_type'];
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001162 $wm_width = $props['width'];
1163 $wm_height = $props['height'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001164
Andrey Andreev8e70b792012-01-12 20:19:24 +02001165 // Create two image resources
Derek Jones4b9c6292011-07-01 17:40:48 -05001166 $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001167 $src_img = $this->image_create_gd($this->full_src_path);
1168
1169 // Reverse the offset if necessary
1170 // When the image is positioned at the bottom
1171 // we don't want the vertical offset to push it
Andrey Andreev8e70b792012-01-12 20:19:24 +02001172 // further down. We want the reverse, so we'll
1173 // invert the offset. Same with the horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001174 // offset when the image is at the right
1175
Andrey Andreev8e70b792012-01-12 20:19:24 +02001176 $this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
1177 $this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001178
Alex Bilbied261b1e2012-06-02 11:12:16 +01001179 if ($this->wm_vrt_alignment === 'B')
Derek Allard2067d1a2008-11-13 22:59:24 +00001180 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
1181
Alex Bilbied261b1e2012-06-02 11:12:16 +01001182 if ($this->wm_hor_alignment === 'R')
Derek Allard2067d1a2008-11-13 22:59:24 +00001183 $this->wm_hor_offset = $this->wm_hor_offset * -1;
1184
Andrey Andreev8e70b792012-01-12 20:19:24 +02001185 // Set the base x and y axis values
Derek Allard2067d1a2008-11-13 22:59:24 +00001186 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1187 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1188
Andrey Andreev8e70b792012-01-12 20:19:24 +02001189 // Set the vertical position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001190 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001191 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001192 $y_axis += ($this->orig_height / 2) - ($wm_height / 2);
1193 }
1194 elseif ($this->wm_vrt_alignment === 'B')
1195 {
1196 $y_axis += $this->orig_height - $wm_height;
Derek Allard2067d1a2008-11-13 22:59:24 +00001197 }
1198
Andrey Andreev8e70b792012-01-12 20:19:24 +02001199 // Set the horizontal position
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001200 if ($this->wm_hor_alignment === 'C')
Derek Allard2067d1a2008-11-13 22:59:24 +00001201 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001202 $x_axis += ($this->orig_width / 2) - ($wm_width / 2);
1203 }
1204 elseif ($this->wm_hor_alignment === 'R')
1205 {
1206 $x_axis += $this->orig_width - $wm_width;
Derek Allard2067d1a2008-11-13 22:59:24 +00001207 }
1208
Andrey Andreev10fb7d12015-08-03 10:05:29 +03001209 // Build the finalized image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001210 if ($wm_img_type === 3 && function_exists('imagealphablending'))
Derek Allard2067d1a2008-11-13 22:59:24 +00001211 {
1212 @imagealphablending($src_img, TRUE);
Barry Mienydd671972010-10-04 16:33:58 +02001213 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001214
1215 // Set RGB values for text and shadow
1216 $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
1217 $alpha = ($rgba & 0x7F000000) >> 24;
1218
1219 // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1220 if ($alpha > 0)
1221 {
1222 // copy the image directly, the image's alpha transparency being the sole determinant of blending
1223 imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
1224 }
1225 else
1226 {
1227 // set our RGB value from above to be transparent and merge the images with the specified opacity
1228 imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
1229 imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
1230 }
1231
Andrey Andreevdb037db2015-01-12 13:45:12 +02001232 // We can preserve transparency for PNG images
Дмитрийb23b8fc2014-10-20 00:36:55 +04001233 if ($this->image_type === 3)
1234 {
1235 imagealphablending($src_img, FALSE);
1236 imagesavealpha($src_img, TRUE);
1237 }
1238
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001239 // Output the image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001240 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001241 {
1242 $this->image_display_gd($src_img);
1243 }
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001244 elseif ( ! $this->image_save_gd($src_img)) // ... or save it
Derek Allard2067d1a2008-11-13 22:59:24 +00001245 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001246 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001247 }
1248
1249 imagedestroy($src_img);
1250 imagedestroy($wm_img);
1251
1252 return TRUE;
1253 }
1254
1255 // --------------------------------------------------------------------
1256
1257 /**
1258 * Watermark - Text Version
1259 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001260 * @return bool
1261 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001262 public function text_watermark()
Derek Allard2067d1a2008-11-13 22:59:24 +00001263 {
1264 if ( ! ($src_img = $this->image_create_gd()))
1265 {
1266 return FALSE;
1267 }
1268
Alex Bilbied261b1e2012-06-02 11:12:16 +01001269 if ($this->wm_use_truetype === TRUE && ! file_exists($this->wm_font_path))
Derek Allard2067d1a2008-11-13 22:59:24 +00001270 {
1271 $this->set_error('imglib_missing_font');
1272 return FALSE;
1273 }
1274
Andrey Andreev8e70b792012-01-12 20:19:24 +02001275 // Fetch source image properties
Derek Allard2067d1a2008-11-13 22:59:24 +00001276 $this->get_image_properties();
1277
Derek Allard2067d1a2008-11-13 22:59:24 +00001278 // Reverse the vertical offset
1279 // When the image is positioned at the bottom
1280 // we don't want the vertical offset to push it
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001281 // further down. We want the reverse, so we'll
Andrey Andreev8e70b792012-01-12 20:19:24 +02001282 // invert the offset. Note: The horizontal
Derek Allard2067d1a2008-11-13 22:59:24 +00001283 // offset flips itself automatically
1284
Alex Bilbied261b1e2012-06-02 11:12:16 +01001285 if ($this->wm_vrt_alignment === 'B')
Andrey Andreeve52fc262014-02-11 13:27:01 +02001286 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001287 $this->wm_vrt_offset = $this->wm_vrt_offset * -1;
Andrey Andreeve52fc262014-02-11 13:27:01 +02001288 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001289
Alex Bilbied261b1e2012-06-02 11:12:16 +01001290 if ($this->wm_hor_alignment === 'R')
Andrey Andreeve52fc262014-02-11 13:27:01 +02001291 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001292 $this->wm_hor_offset = $this->wm_hor_offset * -1;
Andrey Andreeve52fc262014-02-11 13:27:01 +02001293 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001294
1295 // Set font width and height
1296 // These are calculated differently depending on
1297 // whether we are using the true type font or not
Alex Bilbied261b1e2012-06-02 11:12:16 +01001298 if ($this->wm_use_truetype === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001299 {
Andrey Andreeve52fc262014-02-11 13:27:01 +02001300 if (empty($this->wm_font_size))
Andrey Andreeva92b9032011-12-24 19:05:58 +02001301 {
1302 $this->wm_font_size = 17;
1303 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001304
Andrey Andreeve52fc262014-02-11 13:27:01 +02001305 if (function_exists('imagettfbbox'))
1306 {
1307 $temp = imagettfbbox($this->wm_font_size, 0, $this->wm_font_path, $this->wm_text);
1308 $temp = $temp[2] - $temp[0];
1309
1310 $fontwidth = $temp / strlen($this->wm_text);
1311 }
1312 else
1313 {
1314 $fontwidth = $this->wm_font_size - ($this->wm_font_size / 4);
1315 }
1316
Derek Allard2067d1a2008-11-13 22:59:24 +00001317 $fontheight = $this->wm_font_size;
1318 $this->wm_vrt_offset += $this->wm_font_size;
1319 }
1320 else
1321 {
Derek Jones4b9c6292011-07-01 17:40:48 -05001322 $fontwidth = imagefontwidth($this->wm_font_size);
Derek Allard2067d1a2008-11-13 22:59:24 +00001323 $fontheight = imagefontheight($this->wm_font_size);
1324 }
1325
1326 // Set base X and Y axis values
1327 $x_axis = $this->wm_hor_offset + $this->wm_padding;
1328 $y_axis = $this->wm_vrt_offset + $this->wm_padding;
1329
Alex Bilbied261b1e2012-06-02 11:12:16 +01001330 if ($this->wm_use_drop_shadow === FALSE)
omar0779e992015-01-31 11:57:07 -07001331 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001332 $this->wm_shadow_distance = 0;
omar0779e992015-01-31 11:57:07 -07001333 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001334
Andrey Andreev7a7ad782012-11-12 17:21:01 +02001335 $this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
1336 $this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001337
omar0779e992015-01-31 11:57:07 -07001338 // Set vertical alignment
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001339 if ($this->wm_vrt_alignment === 'M')
Derek Allard2067d1a2008-11-13 22:59:24 +00001340 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001341 $y_axis += ($this->orig_height / 2) + ($fontheight / 2);
1342 }
1343 elseif ($this->wm_vrt_alignment === 'B')
1344 {
1345 $y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2);
Derek Allard2067d1a2008-11-13 22:59:24 +00001346 }
Andrey Andreev3a197592015-05-21 01:05:06 +03001347
omar0779e992015-01-31 11:57:07 -07001348 // Set horizontal alignment
1349 if ($this->wm_hor_alignment === 'R')
1350 {
omar9c855322015-01-31 11:58:03 -07001351 $x_axis += $this->orig_width - ($fontwidth * strlen($this->wm_text)) - $this->wm_shadow_distance;
omar0779e992015-01-31 11:57:07 -07001352 }
1353 elseif ($this->wm_hor_alignment === 'C')
1354 {
1355 $x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
1356 }
Andrey Andreev3a197592015-05-21 01:05:06 +03001357
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001358 if ($this->wm_use_drop_shadow)
Derek Allard2067d1a2008-11-13 22:59:24 +00001359 {
omar0779e992015-01-31 11:57:07 -07001360 // Offset from text
1361 $x_shad = $x_axis + $this->wm_shadow_distance;
1362 $y_shad = $y_axis + $this->wm_shadow_distance;
Andrey Andreev3a197592015-05-21 01:05:06 +03001363
omar0779e992015-01-31 11:57:07 -07001364 /* Set RGB values for shadow
Andrey Andreev8323ae62011-12-31 18:39:10 +02001365 *
1366 * First character is #, so we don't really need it.
1367 * Get the rest of the string and split it into 2-length
1368 * hex values:
1369 */
Andrey Andreev8323ae62011-12-31 18:39:10 +02001370 $drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
Ronald Beilsma8f80bc42012-01-12 16:41:49 +01001371 $drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
Andrey Andreev3a197592015-05-21 01:05:06 +03001372
omar0779e992015-01-31 11:57:07 -07001373 // Add the shadow to the source image
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001374 if ($this->wm_use_truetype)
1375 {
1376 imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001377 }
1378 else
1379 {
1380 imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
Andrey Andreev64dbdfb2011-12-30 14:14:07 +02001381 }
omar0779e992015-01-31 11:57:07 -07001382 }
Andrey Andreev3a197592015-05-21 01:05:06 +03001383
omar0779e992015-01-31 11:57:07 -07001384 /* Set RGB values for text
1385 *
1386 * First character is #, so we don't really need it.
1387 * Get the rest of the string and split it into 2-length
1388 * hex values:
1389 */
1390 $txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
1391 $txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
Andrey Andreev99ae2262012-10-05 15:14:30 +03001392
omar0779e992015-01-31 11:57:07 -07001393 // Add the text to the source image
1394 if ($this->wm_use_truetype)
1395 {
1396 imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
1397 }
1398 else
1399 {
1400 imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
1401 }
Andrey Andreev3a197592015-05-21 01:05:06 +03001402
omar0779e992015-01-31 11:57:07 -07001403 // We can preserve transparency for PNG images
1404 if ($this->image_type === 3)
1405 {
1406 imagealphablending($src_img, FALSE);
1407 imagesavealpha($src_img, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001408 }
1409
Andrey Andreev8e70b792012-01-12 20:19:24 +02001410 // Output the final image
Alex Bilbied261b1e2012-06-02 11:12:16 +01001411 if ($this->dynamic_output === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001412 {
1413 $this->image_display_gd($src_img);
1414 }
1415 else
1416 {
1417 $this->image_save_gd($src_img);
1418 }
1419
1420 imagedestroy($src_img);
1421
1422 return TRUE;
1423 }
1424
1425 // --------------------------------------------------------------------
1426
1427 /**
1428 * Create Image - GD
1429 *
1430 * This simply creates an image resource handle
1431 * based on the type of image being processed
1432 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001433 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001434 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001435 * @return resource
1436 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001437 public function image_create_gd($path = '', $image_type = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001438 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001439 if ($path === '')
Andrey Andreeve52fc262014-02-11 13:27:01 +02001440 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001441 $path = $this->full_src_path;
Andrey Andreeve52fc262014-02-11 13:27:01 +02001442 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001443
Alex Bilbied261b1e2012-06-02 11:12:16 +01001444 if ($image_type === '')
Andrey Andreeve52fc262014-02-11 13:27:01 +02001445 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001446 $image_type = $this->image_type;
Andrey Andreeve52fc262014-02-11 13:27:01 +02001447 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001448
Derek Allard2067d1a2008-11-13 22:59:24 +00001449 switch ($image_type)
1450 {
Andrey Andreev3a197592015-05-21 01:05:06 +03001451 case 1:
Andrey Andreeve52fc262014-02-11 13:27:01 +02001452 if ( ! function_exists('imagecreatefromgif'))
1453 {
1454 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1455 return FALSE;
1456 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001457
Andrey Andreeve52fc262014-02-11 13:27:01 +02001458 return imagecreatefromgif($path);
Andrey Andreev3a197592015-05-21 01:05:06 +03001459 case 2:
Andrey Andreeve52fc262014-02-11 13:27:01 +02001460 if ( ! function_exists('imagecreatefromjpeg'))
1461 {
1462 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1463 return FALSE;
1464 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001465
Andrey Andreeve52fc262014-02-11 13:27:01 +02001466 return imagecreatefromjpeg($path);
Andrey Andreev3a197592015-05-21 01:05:06 +03001467 case 3:
Andrey Andreeve52fc262014-02-11 13:27:01 +02001468 if ( ! function_exists('imagecreatefrompng'))
1469 {
1470 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1471 return FALSE;
1472 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001473
Andrey Andreeve52fc262014-02-11 13:27:01 +02001474 return imagecreatefrompng($path);
1475 default:
1476 $this->set_error(array('imglib_unsupported_imagecreate'));
1477 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001478 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001479 }
1480
1481 // --------------------------------------------------------------------
1482
1483 /**
1484 * Write image file to disk - GD
1485 *
1486 * Takes an image resource as input and writes the file
1487 * to the specified destination
1488 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001489 * @param resource
1490 * @return bool
1491 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001492 public function image_save_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001493 {
1494 switch ($this->image_type)
1495 {
Andrey Andreev56454792012-05-17 14:32:19 +03001496 case 1:
1497 if ( ! function_exists('imagegif'))
1498 {
1499 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
1500 return FALSE;
1501 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001502
Andrey Andreev56454792012-05-17 14:32:19 +03001503 if ( ! @imagegif($resource, $this->full_dst_path))
1504 {
1505 $this->set_error('imglib_save_failed');
1506 return FALSE;
1507 }
1508 break;
1509 case 2:
1510 if ( ! function_exists('imagejpeg'))
1511 {
1512 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
1513 return FALSE;
1514 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001515
Andrey Andreev56454792012-05-17 14:32:19 +03001516 if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
1517 {
1518 $this->set_error('imglib_save_failed');
1519 return FALSE;
1520 }
1521 break;
1522 case 3:
1523 if ( ! function_exists('imagepng'))
1524 {
1525 $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
1526 return FALSE;
1527 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001528
Andrey Andreev56454792012-05-17 14:32:19 +03001529 if ( ! @imagepng($resource, $this->full_dst_path))
1530 {
1531 $this->set_error('imglib_save_failed');
1532 return FALSE;
1533 }
1534 break;
1535 default:
1536 $this->set_error(array('imglib_unsupported_imagecreate'));
1537 return FALSE;
1538 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001539 }
1540
1541 return TRUE;
1542 }
1543
1544 // --------------------------------------------------------------------
1545
1546 /**
1547 * Dynamically outputs an image
1548 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001549 * @param resource
1550 * @return void
1551 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001552 public function image_display_gd($resource)
Derek Allard2067d1a2008-11-13 22:59:24 +00001553 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001554 header('Content-Disposition: filename='.$this->source_image.';');
1555 header('Content-Type: '.$this->mime_type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001556 header('Content-Transfer-Encoding: binary');
1557 header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
1558
1559 switch ($this->image_type)
1560 {
Andrey Andreev56454792012-05-17 14:32:19 +03001561 case 1 : imagegif($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001562 break;
Ted Wood9cc707b2013-01-08 19:41:45 -08001563 case 2 : imagejpeg($resource, NULL, $this->quality);
Derek Allard2067d1a2008-11-13 22:59:24 +00001564 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001565 case 3 : imagepng($resource);
Derek Allard2067d1a2008-11-13 22:59:24 +00001566 break;
Andrey Andreev56454792012-05-17 14:32:19 +03001567 default: echo 'Unable to display the image';
Derek Allard2067d1a2008-11-13 22:59:24 +00001568 break;
1569 }
1570 }
1571
1572 // --------------------------------------------------------------------
1573
1574 /**
1575 * Re-proportion Image Width/Height
1576 *
1577 * When creating thumbs, the desired width/height
1578 * can end up warping the image due to an incorrect
1579 * ratio between the full-sized image and the thumb.
1580 *
1581 * This function lets us re-proportion the width/height
1582 * if users choose to maintain the aspect ratio when resizing.
1583 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001584 * @return void
1585 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001586 public function image_reproportion()
Derek Allard2067d1a2008-11-13 22:59:24 +00001587 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001588 if (($this->width === 0 && $this->height === 0) OR $this->orig_width === 0 OR $this->orig_height === 0
Andrey Andreev7a7ad782012-11-12 17:21:01 +02001589 OR ( ! ctype_digit((string) $this->width) && ! ctype_digit((string) $this->height))
1590 OR ! ctype_digit((string) $this->orig_width) OR ! ctype_digit((string) $this->orig_height))
Derek Allard2067d1a2008-11-13 22:59:24 +00001591 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001592 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001593 }
1594
Andrey Andreev7a7ad782012-11-12 17:21:01 +02001595 // Sanitize
Andrey Andreev8e70b792012-01-12 20:19:24 +02001596 $this->width = (int) $this->width;
1597 $this->height = (int) $this->height;
1598
1599 if ($this->master_dim !== 'width' && $this->master_dim !== 'height')
Derek Allard2067d1a2008-11-13 22:59:24 +00001600 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001601 if ($this->width > 0 && $this->height > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001602 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001603 $this->master_dim = ((($this->orig_height/$this->orig_width) - ($this->height/$this->width)) < 0)
1604 ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001605 }
1606 else
1607 {
Andrey Andreev8e70b792012-01-12 20:19:24 +02001608 $this->master_dim = ($this->height === 0) ? 'width' : 'height';
Derek Allard2067d1a2008-11-13 22:59:24 +00001609 }
1610 }
Andrey Andreev8e70b792012-01-12 20:19:24 +02001611 elseif (($this->master_dim === 'width' && $this->width === 0)
1612 OR ($this->master_dim === 'height' && $this->height === 0))
1613 {
1614 return;
1615 }
1616
1617 if ($this->master_dim === 'width')
1618 {
1619 $this->height = (int) ceil($this->width*$this->orig_height/$this->orig_width);
1620 }
1621 else
1622 {
1623 $this->width = (int) ceil($this->orig_width*$this->height/$this->orig_height);
1624 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001625 }
1626
1627 // --------------------------------------------------------------------
1628
1629 /**
1630 * Get image properties
1631 *
1632 * A helper function that gets info about the file
1633 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001634 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001635 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +00001636 * @return mixed
1637 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001638 public function get_image_properties($path = '', $return = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001639 {
1640 // For now we require GD but we should
1641 // find a way to determine this using IM or NetPBM
1642
Alex Bilbied261b1e2012-06-02 11:12:16 +01001643 if ($path === '')
Andrey Andreev8e70b792012-01-12 20:19:24 +02001644 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001645 $path = $this->full_src_path;
Andrey Andreev8e70b792012-01-12 20:19:24 +02001646 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001647
1648 if ( ! file_exists($path))
1649 {
1650 $this->set_error('imglib_invalid_path');
1651 return FALSE;
1652 }
1653
Phil Sturgeon901998a2011-08-26 10:03:33 +01001654 $vals = getimagesize($path);
Andrey Andreev747deff2017-01-06 13:22:16 +02001655 if ($vals === FALSE)
1656 {
1657 $this->set_error('imglib_invalid_image');
1658 return FALSE;
1659 }
Andrey Andreev5f7302c2017-01-06 13:26:08 +02001660
Derek Allard2067d1a2008-11-13 22:59:24 +00001661 $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
Andrey Andreev5f7302c2017-01-06 13:26:08 +02001662 $mime = isset($types[$vals[2]]) ? 'image/'.$types[$vals[2]] : 'image/jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001663
Alex Bilbied261b1e2012-06-02 11:12:16 +01001664 if ($return === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001665 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001666 return array(
Andrey Andreev5f7302c2017-01-06 13:26:08 +02001667 'width' => $vals[0],
1668 'height' => $vals[1],
1669 'image_type' => $vals[2],
1670 'size_str' => $vals[3],
1671 'mime_type' => $mime
1672 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001673 }
1674
Andrey Andreev5f7302c2017-01-06 13:26:08 +02001675 $this->orig_width = $vals[0];
1676 $this->orig_height = $vals[1];
1677 $this->image_type = $vals[2];
1678 $this->size_str = $vals[3];
1679 $this->mime_type = $mime;
Derek Allard2067d1a2008-11-13 22:59:24 +00001680
1681 return TRUE;
1682 }
1683
1684 // --------------------------------------------------------------------
1685
1686 /**
1687 * Size calculator
1688 *
1689 * This function takes a known width x height and
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001690 * recalculates it to a new size. Only one
Derek Allard2067d1a2008-11-13 22:59:24 +00001691 * new variable needs to be known
1692 *
1693 * $props = array(
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001694 * 'width' => $width,
1695 * 'height' => $height,
1696 * 'new_width' => 40,
1697 * 'new_height' => ''
1698 * );
Derek Allard2067d1a2008-11-13 22:59:24 +00001699 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001700 * @param array
1701 * @return array
1702 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001703 public function size_calculator($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001704 {
1705 if ( ! is_array($vals))
1706 {
1707 return;
1708 }
1709
1710 $allowed = array('new_width', 'new_height', 'width', 'height');
1711
1712 foreach ($allowed as $item)
1713 {
Andrey Andreev56454792012-05-17 14:32:19 +03001714 if (empty($vals[$item]))
1715 {
Derek Allard2067d1a2008-11-13 22:59:24 +00001716 $vals[$item] = 0;
Andrey Andreev56454792012-05-17 14:32:19 +03001717 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001718 }
1719
Alex Bilbied261b1e2012-06-02 11:12:16 +01001720 if ($vals['width'] === 0 OR $vals['height'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001721 {
1722 return $vals;
1723 }
1724
Alex Bilbied261b1e2012-06-02 11:12:16 +01001725 if ($vals['new_width'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001726 {
1727 $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1728 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001729 elseif ($vals['new_height'] === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001730 {
1731 $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1732 }
1733
1734 return $vals;
1735 }
1736
1737 // --------------------------------------------------------------------
1738
1739 /**
1740 * Explode source_image
1741 *
1742 * This is a helper function that extracts the extension
Derek Jones4b9c6292011-07-01 17:40:48 -05001743 * from the source_image. This function lets us deal with
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001744 * source_images with multiple periods, like: my.cool.jpg
Derek Allard2067d1a2008-11-13 22:59:24 +00001745 * It returns an associative array with two elements:
Derek Jones4b9c6292011-07-01 17:40:48 -05001746 * $array['ext'] = '.jpg';
Derek Allard2067d1a2008-11-13 22:59:24 +00001747 * $array['name'] = 'my.cool';
1748 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001749 * @param array
1750 * @return array
1751 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001752 public function explode_name($source_image)
Derek Allard2067d1a2008-11-13 22:59:24 +00001753 {
Derek Jones08cae632009-02-10 20:03:29 +00001754 $ext = strrchr($source_image, '.');
1755 $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
Barry Mienydd671972010-10-04 16:33:58 +02001756
Derek Jones08cae632009-02-10 20:03:29 +00001757 return array('ext' => $ext, 'name' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001758 }
1759
1760 // --------------------------------------------------------------------
1761
1762 /**
1763 * Is GD Installed?
1764 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001765 * @return bool
1766 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001767 public function gd_loaded()
Derek Allard2067d1a2008-11-13 22:59:24 +00001768 {
1769 if ( ! extension_loaded('gd'))
1770 {
Andrey Andreeva92b9032011-12-24 19:05:58 +02001771 /* As it is stated in the PHP manual, dl() is not always available
1772 * and even if so - it could generate an E_WARNING message on failure
1773 */
Andrey Andreev8e70b792012-01-12 20:19:24 +02001774 return (function_exists('dl') && @dl('gd.so'));
Derek Allard2067d1a2008-11-13 22:59:24 +00001775 }
1776
1777 return TRUE;
1778 }
1779
1780 // --------------------------------------------------------------------
1781
1782 /**
1783 * Get GD version
1784 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001785 * @return mixed
1786 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001787 public function gd_version()
Derek Allard2067d1a2008-11-13 22:59:24 +00001788 {
1789 if (function_exists('gd_info'))
1790 {
1791 $gd_version = @gd_info();
Andrey Andreev8e70b792012-01-12 20:19:24 +02001792 return preg_replace('/\D/', '', $gd_version['GD Version']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001793 }
1794
1795 return FALSE;
1796 }
1797
1798 // --------------------------------------------------------------------
1799
1800 /**
1801 * Set error message
1802 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001803 * @param string
1804 * @return void
1805 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001806 public function set_error($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +00001807 {
1808 $CI =& get_instance();
1809 $CI->lang->load('imglib');
1810
1811 if (is_array($msg))
1812 {
1813 foreach ($msg as $val)
1814 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001815 $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
Derek Allard2067d1a2008-11-13 22:59:24 +00001816 $this->error_msg[] = $msg;
1817 log_message('error', $msg);
1818 }
1819 }
1820 else
1821 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001822 $msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg);
Derek Allard2067d1a2008-11-13 22:59:24 +00001823 $this->error_msg[] = $msg;
1824 log_message('error', $msg);
1825 }
1826 }
1827
1828 // --------------------------------------------------------------------
1829
1830 /**
1831 * Show error messages
1832 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001833 * @param string
Timothy Warrenb82bc3a2012-04-27 09:12:58 -04001834 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +00001835 * @return string
1836 */
Andrey Andreev4eea9892011-12-19 12:05:41 +02001837 public function display_errors($open = '<p>', $close = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +00001838 {
Andrey Andreev2c8baeb2012-01-19 15:45:28 +02001839 return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001840 }
1841
1842}