image_library.php
1 <?php
2
/**
3  * Image Manipulation Library
4  *
5  * @author Zhou Yuan <yuanzhou19@gmail.com>
6  * @link http://www.infopotato.com/
7  * @link        http://codeigniter.com/user_guide/libraries/image_lib.html
8  * @copyright Copyright &copy; 2009-2011 Zhou Yuan
9  * @license http://www.opensource.org/licenses/mit-license.php MIT Licence
10  */
11
class Image_Library {
12     
/**
13      * Sets the image library to be used (Can be:  imagemagick, netpbm, gd, gd2)
14      * 
15      * Availability: R, C, X, W
16      * 
17      * @var string 
18      */
19     
public $image_library_to_use 'gd2';
20     
21     
/**
22      * Sets the server path to your ImageMagick or NetPBM library. 
23      * If you use either of those libraries you must supply the path.
24      * 
25      * Availability: R, C, X
26      * 
27      * @var string 
28      */
29     
public $library_path '';
30     
31     
/**
32      * Determines whether the new image file should be written to disk or generated dynamically. 
33      * Whether to send to browser or write to disk
34      * Note: If you choose the dynamic setting, only one image can be shown at a time, 
35      * and it can't be positioned on the page. 
36      * It simply outputs the raw image dynamically to your browser, along with image headers.
37      * 
38      * Availability: R, C, X, W
39      * 
40      * @var string 
41      */
42     
public $dynamic_output FALSE;    
43     
44     
/**
45      * Sets the source image name/path. 
46      * The path must be a relative or absolute server path, not a URL.
47      * 
48      * Availability: R, C, X, W
49      * 
50      * @var string 
51      */
52     
public $source_image '';
53     
54     
/**
55      * Sets the destination image name/path. You'll use this preference when creating an image copy. 
56      * The path must be a relative or absolute server path, not a URL.
57      * 
58      * Availability: R, C, X, W
59      * 
60      * @var string 
61      */
62     
public $new_image '';
63     
64     
/**
65      * Sets the width you would like the image set to.
66      * 
67      * Availability: R, C
68      * 
69      * @var string 
70      */
71     
public $width '';
72     
73     
/**
74      * Sets the height you would like the image set to.
75      * 
76      * Availability: R, C
77      * 
78      * @var string 
79      */
80     
public $height '';
81     
82     
/**
83      * Sets the quality of the image. The higher the quality the larger the file size.
84      * 
85      * Availability: R, C, X, W
86      * 
87      * @var string 
88      */
89     
public $quality '90';
90     
91     
/**
92      * Tells the image processing function to create a thumb.
93      * 
94      * Availability: R
95      * 
96      * @var boolean
97      */
98     
public $create_thumb FALSE;
99     
100     
/**
101      * Specifies the thumbnail indicator. It will be inserted just before the file extension, 
102      * so mypic.jpg would become mypic_thumb.jpg 
103      * 
104      * Availability: R
105      * 
106      * @var string 
107      */
108     
public $thumb_marker '_thumb';
109     
110     
/**
111      * Specifies whether to maintain the original aspect ratio when resizing or use hard values.
112      * 
113      * Availability: R, C
114      * 
115      * @var boolean
116      */
117     
public $maintain_ratio TRUE;    
118     
119     
/**
120      * Specifies what to use as the master axis when resizing or creating thumbs. 
121      * For example, let's say you want to resize an image to 100 X 75 pixels. 
122      * If the source image size does not allow perfect resizing to those dimensions, 
123      * this setting determines which axis should be used as the hard value. 
124      * "auto" sets the axis automatically based on whether the image is taller then wider, or vice versa.
125      *
126      * auto, height, or width.  Determines what to use as the master dimension
127      * 
128      * Availability: R
129      * 
130      * @var string 
131      */
132     
public $master_dim 'auto';
133     
134     
/**
135      * Specifies the angle of rotation when rotating images. 
136      * Note that PHP rotates counter-clockwise, 
137      * so a 90 degree rotation to the right must be specified as 270.
138      * 
139      * Availability: X
140      * 
141      * @var string 
142      */
143     
public $rotation_angle '';
144     
145     
/**
146      * Sets the X coordinate in pixels for image cropping. 
147      * For example, a setting of 30 will crop an image 30 pixels from the left.
148      * 
149      * Availability: C
150      * 
151      * @var string 
152      */
153     
public $x_axis '';
154     
155     
/**
156      * Sets the Y coordinate in pixels for image cropping. 
157      * For example, a setting of 30 will crop an image 30 pixels from the top.
158      * 
159      * Availability: C
160      * 
161      * @var string 
162      */
163     
public $y_axis '';
164
165     
// Watermark Vars
166     
167     /**
168      * The text you would like shown as the watermark. 
169      * Typically this will be a copyright notice.
170      * 
171      * @var string 
172      */
173     
public $wm_text '';
174     
175     
/**
176      * Sets the type of watermarking that should be used.
177      * Options:  text/overlay
178      * 
179      * @var string 
180      */
181     
public $wm_type 'text';
182     
183     
/**
184      * If your watermark image is a PNG or GIF image, 
185      * you may specify a color on the image to be "transparent". 
186      * This setting (along with the next) will allow you to specify that color. 
187      * This works by specifying the "X" and "Y" coordinate pixel (measured from the upper left) 
188      * within the image that corresponds to a pixel representative of the color you want to be transparent.
189      * 
190      * @var integer
191      */
192     
public $wm_x_transp    4;
193     
194     
/**
195      * Along with the previous setting, this allows you to specify the coordinate 
196      * to a pixel representative of the color you want to be transparent.
197      * 
198      * @var integer
199      */
200     
public $wm_y_transp 4;
201     
202     
/**
203      * The server path to the image you wish to use as your watermark. 
204      * Required only if you are using the overlay method.
205      * 
206      * @var string 
207      */
208     
public $wm_overlay_path    '';
209     
210     
/**
211      * The server path to the True Type Font you would like to use. 
212      * If you do not use this option, the native GD font will be used.
213      * 
214      * @var string 
215      */
216     
public $wm_font_path '';
217     
218     
/**
219      * The size of the text. Note: If you are not using the True Type option above, 
220      * the number is set using a range of 1 - 5. 
221      * Otherwise, you can use any valid pixel size for the font you're using.
222      * 
223      * @var integer
224      */
225     
public $wm_font_size 17;
226     
227     
/**
228      * Sets the vertical alignment for the watermark image.
229      * Vertical alignment:   T M B
230      * 
231      * @var string 
232      */
233     
public $wm_vrt_alignment 'B';
234     
235     
/**
236      * Sets the horizontal alignment for the watermark image.
237      * Horizontal alignment: L R C
238      * 
239      * @var string 
240      */
241     
public $wm_hor_alignment 'C';    
242     
243     
/**
244      * The amount of padding around text, set in pixels, 
245      * that will be applied to the watermark to set it away from the edge of your images.
246      * 
247      * @var integer
248      */
249     
public $wm_padding 0;
250     
251     
/**
252      * You may specify a horizontal offset (in pixels) to apply to the watermark position. 
253      * The offset normally moves the watermark to the right, except if you have your alignment 
254      * set to "right" then your offset value will move the watermark toward the left of the image.
255      * 
256      * @var integer
257      */
258     
public $wm_hor_offset 0;
259     
260     
/**
261      * You may specify a vertical offset (in pixels) to apply to the watermark position. 
262      * The offset normally moves the watermark down, except if you have your alignment 
263      * set to "bottom" then your offset value will move the watermark toward the top of the image.
264      * 
265      * @var integer
266      */
267     
public $wm_vrt_offset 0;
268     
269     
/**
270      * The font color, specified in hex. 
271      * Note, you must use the full 6 character hex value (ie, 993300), 
272      * rather than the three character abbreviated version (ie fff).
273      * 
274      * @var string 
275      */
276     
public $wm_font_color '#ffffff';
277     
278     
/**
279      * The color of the drop shadow, specified in hex. 
280      * If you leave this blank a drop shadow will not be used. 
281      * Note, you must use the full 6 character hex value (ie, 993300), 
282      * rather than the three character abbreviated version (ie fff).
283      * 
284      * @var string 
285      */
286     
public $wm_shadow_color    '';
287     
288     
/**
289      * The distance (in pixels) from the font that the drop shadow should appear.
290      * 
291      * @var integer
292      */
293     
public $wm_shadow_distance 2;
294     
295     
/**
296      * Image opacity. You may specify the opacity (i.e. transparency) of your watermark image. 
297      * This allows the watermark to be faint and not completely obscure the details 
298      * from the original image behind it. A 50% opacity is typical.
299      * Image opacity: 1 - 100  Only works with image
300      * 
301      * @var integer
302      */
303     
public $wm_opacity 50;
304
305     
// Private Vars
306     
private $source_folder        '';
307     private 
$dest_folder        '';
308     private 
$mime_type            '';
309     private 
$orig_width            '';
310     private 
$orig_height        '';
311     private 
$image_type            '';
312     private 
$size_str            '';
313     private 
$full_src_path        '';
314     private 
$full_dst_path        '';
315     private 
$create_fnc            'imagecreatetruecolor';
316     private 
$copy_fnc            'imagecopyresampled';
317     private 
$wm_use_drop_shadow    FALSE;
318     private 
$wm_use_truetype    FALSE;
319     
320     
321     
/**
322      * All the pre defined error messages
323      * 
324      * @var array
325      */
326     
private $_error_messages = array();
327     
328     
/**
329      * The errors caputered to display
330      * 
331      * @var array
332      */
333     
private $_error_msg_to_display= array();
334     
335     
/**
336      * Constructor
337      *
338      * @param    string
339      * @return    void
340      */
341     
public function __construct(array $config NULL) {
342         if (
count($config) > 0) {
343             
$default_vars = array(
344                 
'image_library_to_use' => '',
345                 
'library_path'    => '',
346                 
'dynamic_output' => FALSE,
347                 
'source_image' => '',
348                 
'new_image' => '',
349                 
'width' => '',
350                 
'height' => '',
351                 
'quality' => '',
352                 
'create_thumb' => FALSE,
353                 
'thumb_marker' => '_thumb',
354                 
'maintain_ratio' => TRUE,
355                 
'master_dim' => 'auto',
356                 
'rotation_angle' => '',
357                 
'x_axis' => '',
358                 
'y_axis' => '',
359                 
'wm_text' => '',
360                 
'wm_type' => '',
361                 
'wm_x_transp' => 4,
362                 
'wm_y_transp' => 4,
363                 
'wm_overlay_path' => '',
364                 
'wm_font_path' => '',
365                 
'wm_font_size'    => 17,
366                 
'wm_vrt_alignment' => 'B',
367                 
'wm_hor_alignment' => 'C',
368                 
'wm_padding' => 0,
369                 
'wm_hor_offset' => 0,
370                 
'wm_vrt_offset' => 0,
371                 
'wm_font_color' => '#ffffff',
372                 
'wm_shadow_color' => '',
373                 
'wm_shadow_distance' => 2,
374                 
'wm_opacity' => 50
375             
);    
376         
377             foreach (
$default_vars as $key => $val) {
378                 if (isset(
$config[$key])) {
379                     
$this->$key $config[$key];            
380                 }
381             }
382         }
383         
384         
$lang = array(
385             
'en/us' => array(
386                 
'source_image_required' => "You must specify a source image in your preferences.",
387                 
'gd_required' => "The GD image library is required for this feature.",
388                 
'gd_required_for_props' => "Your server must support the GD image library in order to determine the image properties.",
389                 
'unsupported_imagecreate' => "Your server does not support the GD function required to process this type of image.",
390                 
'gif_not_supported' => "GIF images are often not supported due to licensing restrictions.  You may have to use JPG or PNG images instead.",
391                 
'jpg_not_supported' => "JPG images are not supported.",
392                 
'png_not_supported' => "PNG images are not supported.",
393                 
'jpg_or_png_required' => "The image resize protocol specified in your preferences only works with JPEG or PNG image types.",
394                 
'copy_error' => "An error was encountered while attempting to replace the file.  Please make sure your file directory is writable.",
395                 
'rotate_unsupported' => "Image rotation does not appear to be supported by your server.",
396                 
'libpath_invalid' => "The path to your image library is not correct.  Please set the correct path in your image preferences.",
397                 
'image_process_failed' => "Image processing failed.  Please verify that your server supports the chosen protocol and that the path to your image library is correct.",
398                 
'rotation_angle_required' => "An angle of rotation is required to rotate the image.",
399                 
'writing_failed_gif' => "GIF image.",
400                 
'invalid_path' => "The path to the image is not correct.",
401                 
'copy_failed' => "The image copy routine failed.",
402                 
'missing_font' => "Unable to find a font to use.",
403                 
'save_failed' => "Unable to save the image.  Please make sure the image and file directory are writable."
404             
),
405             
406             
'zh/cn' => array(
407                 
'source_image_required' => "必须制定图片",
408                 
'gd_required' => "需要GD类来实现这个功能",
409                 
'gd_required_for_props' => "为了决定图片属性你的服务器必须支持GD图片库",
410                 
'unsupported_imagecreate' => "你的服务器不支持GD类的函数来实现此功能",
411                 
'gif_not_supported' => "GIF images are often not supported due to licensing restrictions.  You may have to use JPG or PNG images instead.",
412                 
'jpg_not_supported' => "不支持JPG格式图片",
413                 
'png_not_supported' => "不支持PNG格式图片",
414                 
'jpg_or_png_required' => "The image resize protocol specified in your preferences only works with JPEG or PNG image types.",
415                 
'copy_error' => "An error was encountered while attempting to replace the file.  Please make sure your file directory is writable.",
416                 
'rotate_unsupported' => "你的服务器不支持图片旋转",
417                 
'libpath_invalid' => "图片库路径不正确,请检查",
418                 
'image_process_failed' => "图片处理失败 Please verify that your server supports the chosen protocol and that the path to your image library is correct.",
419                 
'rotation_angle_required' => "必须制定旋转角度来完成图片旋转",
420                 
'writing_failed_gif' => "GIF image.",
421                 
'invalid_path' => "无效的图片路径",
422                 
'copy_failed' => "复制图片失败",
423                 
'missing_font' => "找不到能用的字体",
424                 
'save_failed' => "无法保存图片,请确保图片和文件目录可写"
425             
),
426         );
427         
428         
$this->_error_messages = (isset($config['lang']) && array_key_exists($config['lang'], $lang)) 
429             ? 
$lang[$config['lang']] 
430             : 
$lang['en/us'];
431         
432         
433         
// Check image preferences
434         
$this->_init();
435     }
436
437     
438     
/**
439      * Check image preferences
440      *
441      * @access    private
442      * @param    array
443      * @return    bool
444      */
445     
private function _init() {
446         
// Is there a source image? If not, there's no reason to continue
447         
if ($this->source_image == '') {
448             
$this->_set_error('source_image_required');
449             return 
FALSE;    
450         }
451
452         
// Is getimagesize() Available?
453         // We use it to determine the image properties (width/height).
454         // Note: We need to figure out how to determine image
455         // properties using ImageMagick and NetPBM
456         
if ( ! function_exists('getimagesize')) {
457             
$this->_set_error('gd_required_for_props');
458             return 
FALSE;
459         }
460
461         
$this->image_library_to_use strtolower($this->image_library_to_use);
462
463         
// Set the full server path
464         // The source image may or may not contain a path.
465         // Either way, we'll try use realpath to generate the
466         // full server path in order to more reliably read it.
467         
if (function_exists('realpath') && @realpath($this->source_image) !== FALSE) {
468             
$full_source_path str_replace("\\""/"realpath($this->source_image));
469         } else {
470             
$full_source_path $this->source_image;
471         }
472
473         
$x explode('/'$full_source_path);
474         
$this->source_image end($x);
475         
$this->source_folder str_replace($this->source_image''$full_source_path);
476
477         
// Set the Image Properties
478         
if ( ! $this->_get_image_properties($this->source_folder.$this->source_image)) {
479             return 
FALSE;    
480         }
481
482         
// Assign the "new" image name/path
483         // If the user has set a "new_image" name it means
484         // we are making a copy of the source image. If not
485         // it means we are altering the original. 
486         // We'll set the destination filename and path accordingly.
487         
if ($this->new_image == '') {
488             
$this->dest_image $this->source_image;
489             
$this->dest_folder $this->source_folder;
490         } else {
491             if (
strpos($this->new_image'/') === FALSE) {
492                 
$this->dest_folder $this->source_folder;
493                 
$this->dest_image $this->new_image;
494             } else {
495                 if (
function_exists('realpath') && @realpath($this->new_image) !== FALSE) {
496                     
$full_dest_path str_replace("\\""/"realpath($this->new_image));
497                 } else {
498                     
$full_dest_path $this->new_image;
499                 }
500
501                 
// Is there a file name?
502                 
if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i"$full_dest_path)) {
503                     
$this->dest_folder $full_dest_path.'/';
504                     
$this->dest_image $this->source_image;
505                 } else {
506                     
$x explode('/'$full_dest_path);
507                     
$this->dest_image end($x);
508                     
$this->dest_folder str_replace($this->dest_image''$full_dest_path);
509                 }
510             }
511         }
512
513         
// Compile the finalized filenames/paths
514         // We'll create two master strings containing the
515         // full server path to the source image and the
516         // full server path to the destination image.
517         // We'll also split the destination image name
518         // so we can insert the thumbnail marker if needed.
519         
if ($this->create_thumb === FALSE || $this->thumb_marker == '') {
520             
$this->thumb_marker '';
521         }
522
523         
$xp    $this->_explode_name($this->dest_image);
524
525         
$filename $xp['name'];
526         
$file_ext $xp['ext'];
527
528         
$this->full_src_path $this->source_folder.$this->source_image;
529         
$this->full_dst_path $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
530
531         
// Should we maintain image proportions?
532         // When creating thumbs or copies, the target width/height
533         // might not be in correct proportion with the source
534         // image's width/height.  We'll recalculate it here.
535         
if ($this->maintain_ratio === TRUE && ($this->width != '' && $this->height != '')) {
536             
$this->_image_reproportion();
537         }
538
539         
// Was a width and height specified?
540         // If the destination width/height was
541         // not submitted we will use the values
542         // from the actual file
543         
if ($this->width == '') {
544             
$this->width $this->orig_width;
545         }
546         
547         if (
$this->height == '') {
548             
$this->height $this->orig_height;
549         }
550         
551         
// Set the quality
552         
$this->quality trim(str_replace("%"""$this->quality));
553
554         if (
$this->quality == '' || $this->quality == || ! is_numeric($this->quality)) {
555             
$this->quality 90;
556         }
557         
558         
// Set the x/y coordinates
559         
$this->x_axis = ($this->x_axis == '' || ! is_numeric($this->x_axis)) ? $this->x_axis;
560         
$this->y_axis = ($this->y_axis == '' || ! is_numeric($this->y_axis)) ? $this->y_axis;
561
562         
// Watermark-related Stuff...
563         
if ($this->wm_font_color != '') {
564             if (
strlen($this->wm_font_color) == 6) {
565                 
$this->wm_font_color '#'.$this->wm_font_color;
566             }
567         }
568
569         if (
$this->wm_shadow_color != '') {
570             if (
strlen($this->wm_shadow_color) == 6) {
571                 
$this->wm_shadow_color '#'.$this->wm_shadow_color;
572             }
573         }
574
575         if (
$this->wm_overlay_path != '') {
576             
$this->wm_overlay_path str_replace("\\""/"realpath($this->wm_overlay_path));
577         }
578
579         if (
$this->wm_shadow_color != '') {
580             
$this->wm_use_drop_shadow TRUE;
581         }
582
583         if (
$this->wm_font_path != '') {
584             
$this->wm_use_truetype TRUE;
585         }
586
587         return 
TRUE;
588     }
589
590
591     
/**
592      * Resets values in case this class is used in a loop
593      *
594      * @access    public
595      * @return    void
596      */
597     
public function clear() {
598         
$props = array('source_folder''dest_folder''source_image''full_src_path''full_dst_path''new_image''image_type''size_str''quality''orig_width''orig_height''rotation_angle''x_axis''y_axis''create_fnc''copy_fnc''wm_overlay_path''wm_use_truetype''dynamic_output''wm_font_size''wm_text''wm_vrt_alignment''wm_hor_alignment''wm_padding''wm_hor_offset''wm_vrt_offset''wm_font_color''wm_use_drop_shadow''wm_shadow_color''wm_shadow_distance''wm_opacity');
599
600         foreach (
$props as $val) {
601             
$this->$val '';
602         }
603
604         
// special consideration for master_dim
605         
$this->master_dim 'auto';
606     }
607     
608     
609     
/**
610      * Image Resize: R
611      *
612      * This is a wrapper function that chooses the proper
613      * resize function based on the protocol specified
614      *
615      * @access    public
616      * @return    bool
617      */
618     
public function resize() {
619         
$protocol '_image_process_'.$this->image_library_to_use;
620
621         if (
preg_match('/gd2$/i'$protocol)) {
622             
$protocol '_image_process_gd';
623         }
624
625         return 
$this->$protocol('resize');
626     }
627
628     
629     
/**
630      * Image Crop: C
631      *
632      * This is a wrapper function that chooses the proper
633      * cropping function based on the protocol specified
634      *
635      * @access    public
636      * @return    bool
637      */
638     
public function crop() {
639         
$protocol '_image_process_'.$this->image_library_to_use;
640
641         if (
preg_match('/gd2$/i'$protocol)) {
642             
$protocol '_image_process_gd';
643         }
644
645         return 
$this->$protocol('crop');
646     }
647
648
649     
/**
650      * Image Rotate: X
651      *
652      * This is a wrapper function that chooses the proper
653      * rotation function based on the protocol specified
654      *
655      * @access    public
656      * @return    bool
657      */
658     
public function rotate() {
659         
// Allowed rotation values
660         
$degs = array(90180270'vrt''hor');
661
662         if (
$this->rotation_angle == '' || ! in_array($this->rotation_angle$degs)) {
663             
$this->_set_error('rotation_angle_required');
664             return 
FALSE;    
665         }
666
667         
// Reassign the width and height
668         
if ($this->rotation_angle == 90 || $this->rotation_angle == 270) {
669             
$this->width $this->orig_height;
670             
$this->height $this->orig_width;
671         } else {
672             
$this->width $this->orig_width;
673             
$this->height $this->orig_height;
674         }
675
676
677         
// Choose resizing function
678         
if ($this->image_library_to_use == 'imagemagick' || $this->image_library_to_use == 'netpbm') {
679             
$protocol '_image_process_'.$this->image_library_to_use;
680
681             return 
$this->$protocol('rotate');
682         }
683
684         if (
$this->rotation_angle == 'hor' || $this->rotation_angle == 'vrt') {
685             return 
$this->_image_mirror_gd();
686         } else {
687             return 
$this->_image_rotate_gd();
688         }
689     }
690
691
692     
/**
693      * Image Process Using GD/GD2
694      *
695      * This function will resize or crop
696      *
697      * @param    string
698      * @return    bool
699      */
700     
private function _image_process_gd($action 'resize') {
701         
$v2_override FALSE;
702
703         
// If the target width/height match the source, AND if the new file name is not equal to the old file name
704         // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
705         
if ($this->dynamic_output === FALSE) {
706             if (
$this->orig_width == $this->width && $this->orig_height == $this->height) {
707                 if (
$this->source_image != $this->new_image) {
708                     if (@
copy($this->full_src_path$this->full_dst_path)) {
709                         @
chmod($this->full_dst_path0666);
710                     }
711                 }
712
713                 return 
TRUE;
714             }
715         }
716
717         
// Let's set up our values based on the action
718         
if ($action == 'crop') {
719             
//  Reassign the source width/height if cropping
720             
$this->orig_width $this->width;
721             
$this->orig_height $this->height;
722
723             
// GD 2.0 has a cropping bug so we'll test for it
724             
if ($this->_gd_version() !== FALSE) {
725                 
$gd_version str_replace('0'''$this->_gd_version());
726                 
$v2_override = ($gd_version == 2) ? TRUE FALSE;
727             }
728         } else {
729             
// If resizing the x/y axis must be zero
730             
$this->x_axis 0;
731             
$this->y_axis 0;
732         }
733
734         
//  Create the image handle
735         
if ( ! ($src_img $this->_image_create_gd())) {
736             return 
FALSE;
737         }
738
739         
//  Create The Image
740         //
741         //  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
742         //  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
743         //  below should that ever prove inaccurate.
744         //
745         //  if ($this->image_library_to_use == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
746         
if ($this->image_library_to_use == 'gd2' && function_exists('imagecreatetruecolor')) {
747             
$create    'imagecreatetruecolor';
748             
$copy 'imagecopyresampled';
749         } else {
750             
$create    'imagecreate';
751             
$copy 'imagecopyresized';
752         }
753
754         
$dst_img $create($this->width$this->height);
755
756         
// png we can actually preserve transparency
757         
if ($this->image_type == 3) {
758             
imagealphablending($dst_imgFALSE);
759             
imagesavealpha($dst_imgTRUE);
760         }
761
762         
$copy($dst_img$src_img00$this->x_axis$this->y_axis$this->width$this->height$this->orig_width$this->orig_height);
763
764         
//  Show the image
765         
if ($this->dynamic_output == TRUE) {
766             
$this->_image_display_gd($dst_img);
767         } else {
768             
// Or save it
769             
if ( ! $this->_image_save_gd($dst_img)) {
770                 return 
FALSE;
771             }
772         }
773
774         
//  Kill the file handles
775         
imagedestroy($dst_img);
776         
imagedestroy($src_img);
777
778         
// Set the file to 777
779         
@chmod($this->full_dst_path0666);
780
781         return 
TRUE;
782     }
783
784
785     
/**
786      * Image Process Using ImageMagick
787      *
788      * This function will resize, crop or rotate
789      *
790      * @param    string
791      * @return    bool
792      */
793     
private function _image_process_imagemagick($action 'resize') {
794         
//  Do we have a vaild library path?
795         
if ($this->library_path == '') {
796             
$this->_set_error('libpath_invalid');
797             return 
FALSE;
798         }
799
800         if ( ! 
preg_match("/convert$/i"$this->library_path)) {
801             
$this->library_path rtrim($this->library_path'/').'/';
802             
$this->library_path .= 'convert';
803         }
804
805         
// Execute the command
806         
$cmd $this->library_path." -quality ".$this->quality;
807
808         if (
$action == 'crop') {
809             
$cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
810         } elseif (
$action == 'rotate') {
811             switch (
$this->rotation_angle) {
812                 case 
'hor'    
813                     
$angle '-flop';
814                     break;
815                 
816                 case 
'vrt' 
817                     
$angle '-flip';
818                     break;
819                 
820                 default : 
821                     
$angle '-rotate '.$this->rotation_angle;
822                     break;
823             }
824
825             
$cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
826         } else {
827             
// Resize
828             
$cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
829         }
830
831         
$retval 1;
832
833         @
exec($cmd$output$retval);
834
835         
//    Did it work?
836         
if ($retval 0) {
837             
$this->_set_error('image_process_failed');
838             return 
FALSE;
839         }
840
841         
// Set the file to 777
842         
@chmod($this->full_dst_path0666);
843
844         return 
TRUE;
845     }
846
847
848     
/**
849      * Image Process Using NetPBM
850      *
851      * This function will resize, crop or rotate
852      *
853      * @param    string
854      * @return    bool
855      */
856     
private function _image_process_netpbm($action 'resize') {
857         if (
$this->library_path == '') {
858             
$this->_set_error('imglib_libpath_invalid');
859             return 
FALSE;
860         }
861
862         
//  Build the resizing command
863         
switch ($this->image_type) {
864             case 
:
865                 
$cmd_in 'giftopnm';
866                 
$cmd_out 'ppmtogif';
867                 break;
868             
869             case 
:
870                 
$cmd_in    'jpegtopnm';
871                 
$cmd_out 'ppmtojpeg';
872                 break;
873             
874             case 
:
875                 
$cmd_in    'pngtopnm';
876                 
$cmd_out 'ppmtopng';
877                 break;
878         }
879
880         if (
$action == 'crop') {
881             
$cmd_inner 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
882         } elseif (
$action == 'rotate') {
883             switch (
$this->rotation_angle) {
884                 case 
90 :    
885                     
$angle 'r270';
886                     break;
887                 
888                 case 
180 :    
889                     
$angle 'r180';
890                     break;
891                 
892                 case 
270 :    
893                     
$angle 'r90';
894                     break;
895                 
896                 case 
'vrt' :    
897                     
$angle 'tb';
898                     break;
899                 
900                 case 
'hor' :    
901                     
$angle 'lr';
902                     break;
903             }
904
905             
$cmd_inner 'pnmflip -'.$angle.' ';
906         } else {
907             
// Resize
908             
$cmd_inner 'pnmscale -xysize '.$this->width.' '.$this->height;
909         }
910
911         
$cmd $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
912
913         
$retval 1;
914
915         @
exec($cmd$output$retval);
916
917         
//  Did it work?
918         
if ($retval 0) {
919             
$this->_set_error('image_process_failed');
920             return 
FALSE;
921         }
922
923         
// With NetPBM we have to create a temporary image.
924         // If you try manipulating the original it fails so
925         // we have to rename the temp file.
926         
copy ($this->dest_folder.'netpbm.tmp'$this->full_dst_path);
927         
unlink ($this->dest_folder.'netpbm.tmp');
928         @
chmod($this->full_dst_path0666);
929
930         return 
TRUE;
931     }
932
933
934     
/**
935      * Image Rotate Using GD
936      *
937      * @return    bool
938      */
939     
private function _image_rotate_gd() {
940         
//  Create the image handle
941         
if ( ! ($src_img $this->_image_create_gd())) {
942             return 
FALSE;
943         }
944
945         
// Set the background color
946         // This won't work with transparent PNG files so we are
947         // going to have to figure out how to determine the color
948         // of the alpha channel in a future release.
949
950         
$white imagecolorallocate($src_img255255255);
951
952         
//  Rotate it!
953         
$dst_img imagerotate($src_img$this->rotation_angle$white);
954
955         
//  Save the Image
956         
if ($this->dynamic_output == TRUE) {
957             
$this->_image_display_gd($dst_img);
958         } else {
959             
// Or save it
960             
if ( ! $this->_image_save_gd($dst_img)) {
961                 return 
FALSE;
962             }
963         }
964
965         
//  Kill the file handles
966         
imagedestroy($dst_img);
967         
imagedestroy($src_img);
968
969         
// Set the file to 777
970
971         
@chmod($this->full_dst_path0666);
972
973         return 
TRUE;
974     }
975
976
977     
/**
978      * Create Mirror Image using GD
979      *
980      * This function will flip horizontal or vertical
981      *
982      * @return    bool
983      */
984     
private function _image_mirror_gd() {
985         if ( ! 
$src_img $this->_image_create_gd()) {
986             return 
FALSE;
987         }
988
989         
$width $this->orig_width;
990         
$height $this->orig_height;
991
992         if (
$this->rotation_angle == 'hor') {
993             for (
$i 0$i $height$i++) {
994                 
$left  0;
995                 
$right $width-1;
996
997                 while (
$left $right) {
998                     
$cl imagecolorat($src_img$left$i);
999                     
$cr imagecolorat($src_img$right$i);
1000
1001                     
imagesetpixel($src_img$left$i$cr);
1002                     
imagesetpixel($src_img$right$i$cl);
1003
1004                     
$left++;
1005                     
$right--;
1006                 }
1007             }
1008         } else {
1009             for (
$i 0$i $width$i++) {
1010                 
$top 0;
1011                 
$bot $height-1;
1012
1013                 while (
$top $bot) {
1014                     
$ct imagecolorat($src_img$i$top);
1015                     
$cb imagecolorat($src_img$i$bot);
1016
1017                     
imagesetpixel($src_img$i$top$cb);
1018                     
imagesetpixel($src_img$i$bot$ct);
1019
1020                     
$top++;
1021                     
$bot--;
1022                 }
1023             }
1024         }
1025
1026         
//  Show the image
1027         
if ($this->dynamic_output == TRUE) {
1028             
$this->_image_display_gd($src_img);
1029         } else {
1030             
// Or save it
1031             
if ( ! $this->_image_save_gd($src_img)) {
1032                 return 
FALSE;
1033             }
1034         }
1035
1036         
//  Kill the file handles
1037         
imagedestroy($src_img);
1038
1039         
// Set the file to 777
1040         
@chmod($this->full_dst_path0666);
1041
1042         return 
TRUE;
1043     }
1044
1045
1046     
/**
1047      * Image Watermark: W
1048      *
1049      * This is a wrapper function that chooses the type
1050      * of watermarking based on the specified preference.
1051      *
1052      * @access    public
1053      * @param    string
1054      * @return    bool
1055      */
1056     
public function watermark() {
1057         if (
$this->wm_type == 'overlay') {
1058             return 
$this->_overlay_watermark();
1059         } else {
1060             return 
$this->_text_watermark();
1061         }
1062     }
1063
1064
1065     
/**
1066      * Watermark - Graphic Version
1067      *
1068      * @return    bool
1069      */
1070     
private function _overlay_watermark() {
1071         if ( ! 
function_exists('imagecolortransparent')) {
1072             
$this->_set_error('gd_required');
1073             return 
FALSE;
1074         }
1075
1076         
//  Fetch source image properties
1077         
$this->_get_image_properties();
1078
1079         
//  Fetch watermark image properties
1080         
$props $this->_get_image_properties($this->wm_overlay_pathTRUE);
1081         
$wm_img_type $props['image_type'];
1082         
$wm_width $props['width'];
1083         
$wm_height $props['height'];
1084
1085         
//  Create two image resources
1086         
$wm_img $this->_image_create_gd($this->wm_overlay_path$wm_img_type);
1087         
$src_img $this->_image_create_gd($this->full_src_path);
1088
1089         
// Reverse the offset if necessary
1090         // When the image is positioned at the bottom
1091         // we don't want the vertical offset to push it
1092         // further down.  We want the reverse, so we'll
1093         // invert the offset.  Same with the horizontal
1094         // offset when the image is at the right
1095
1096         
$this->wm_vrt_alignment strtoupper(substr($this->wm_vrt_alignment01));
1097         
$this->wm_hor_alignment strtoupper(substr($this->wm_hor_alignment01));
1098
1099         if (
$this->wm_vrt_alignment == 'B') {
1100             
$this->wm_vrt_offset $this->wm_vrt_offset * -1;
1101         }
1102         
1103         if (
$this->wm_hor_alignment == 'R') {
1104             
$this->wm_hor_offset $this->wm_hor_offset * -1;
1105         }
1106         
1107         
//  Set the base x and y axis values
1108         
$x_axis $this->wm_hor_offset $this->wm_padding;
1109         
$y_axis $this->wm_vrt_offset $this->wm_padding;
1110
1111         
//  Set the vertical position
1112         
switch ($this->wm_vrt_alignment) {
1113             case 
'T':
1114                 break;
1115             
1116             case 
'M':    
1117                 
$y_axis += ($this->orig_height 2) - ($wm_height 2);
1118                 break;
1119             
1120             case 
'B':    
1121                 
$y_axis += $this->orig_height $wm_height;
1122                 break;
1123         }
1124
1125         
//  Set the horizontal position
1126         
switch ($this->wm_hor_alignment) {
1127             case 
'L':
1128                 break;
1129             
1130             case 
'C':    
1131                 
$x_axis += ($this->orig_width 2) - ($wm_width 2);
1132                 break;
1133             
1134             case 
'R':    
1135                 
$x_axis += $this->orig_width $wm_width;
1136                 break;
1137         }
1138
1139         
//  Build the finalized image
1140         
if ($wm_img_type == && function_exists('imagealphablending')) {
1141             @
imagealphablending($src_imgTRUE);
1142         }
1143
1144         
// Set RGB values for text and shadow
1145         
$rgba imagecolorat($wm_img$this->wm_x_transp$this->wm_y_transp);
1146         
$alpha = ($rgba 0x7F000000) >> 24;
1147
1148         
// make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
1149         
if ($alpha 0) {
1150             
// copy the image directly, the image's alpha transparency being the sole determinant of blending
1151             
imagecopy($src_img$wm_img$x_axis$y_axis00$wm_width$wm_height);
1152         } else {
1153             
// set our RGB value from above to be transparent and merge the images with the specified opacity
1154             
imagecolortransparent($wm_imgimagecolorat($wm_img$this->wm_x_transp$this->wm_y_transp));
1155             
imagecopymerge($src_img$wm_img$x_axis$y_axis00$wm_width$wm_height$this->wm_opacity);
1156         }
1157
1158         
//  Output the image
1159         
if ($this->dynamic_output == TRUE) {
1160             
$this->_image_display_gd($src_img);
1161         } else {
1162             if ( ! 
$this->_image_save_gd($src_img)) {
1163                 return 
FALSE;
1164             }
1165         }
1166
1167         
imagedestroy($src_img);
1168         
imagedestroy($wm_img);
1169
1170         return 
TRUE;
1171     }
1172
1173
1174     
/**
1175      * Watermark - Text Version
1176      *
1177      * @return    bool
1178      */
1179     
private function _text_watermark() {
1180         if ( ! (
$src_img $this->_image_create_gd())) {
1181             return 
FALSE;
1182         }
1183
1184         if (
$this->wm_use_truetype == TRUE && ! file_exists($this->wm_font_path)) {
1185             
$this->_set_error('missing_font');
1186             return 
FALSE;
1187         }
1188
1189         
//  Fetch source image properties
1190         
$this->_get_image_properties();
1191
1192         
// Set RGB values for text and shadow
1193         
$this->wm_font_color    str_replace('#'''$this->wm_font_color);
1194         
$this->wm_shadow_color    str_replace('#'''$this->wm_shadow_color);
1195
1196         
$R1 hexdec(substr($this->wm_font_color02));
1197         
$G1 hexdec(substr($this->wm_font_color22));
1198         
$B1 hexdec(substr($this->wm_font_color42));
1199
1200         
$R2 hexdec(substr($this->wm_shadow_color02));
1201         
$G2 hexdec(substr($this->wm_shadow_color22));
1202         
$B2 hexdec(substr($this->wm_shadow_color42));
1203
1204         
$txt_color    imagecolorclosest($src_img$R1$G1$B1);
1205         
$drp_color    imagecolorclosest($src_img$R2$G2$B2);
1206
1207         
// Reverse the vertical offset
1208         // When the image is positioned at the bottom
1209         // we don't want the vertical offset to push it
1210         // further down.  We want the reverse, so we'll
1211         // invert the offset.  Note: The horizontal
1212         // offset flips itself automatically
1213
1214         
if ($this->wm_vrt_alignment == 'B') {
1215             
$this->wm_vrt_offset $this->wm_vrt_offset * -1;
1216         }
1217         
1218         if (
$this->wm_hor_alignment == 'R') {
1219             
$this->wm_hor_offset $this->wm_hor_offset * -1;
1220         }
1221         
// Set font width and height
1222         // These are calculated differently depending on
1223         // whether we are using the true type font or not
1224         
if ($this->wm_use_truetype == TRUE) {
1225             if (
$this->wm_font_size == '') {
1226                 
$this->wm_font_size '17';
1227             }
1228             
$fontwidth  $this->wm_font_size-($this->wm_font_size/4);
1229             
$fontheight $this->wm_font_size;
1230             
$this->wm_vrt_offset += $this->wm_font_size;
1231         } else {
1232             
$fontwidth  imagefontwidth($this->wm_font_size);
1233             
$fontheight imagefontheight($this->wm_font_size);
1234         }
1235
1236         
// Set base X and Y axis values
1237         
$x_axis $this->wm_hor_offset $this->wm_padding;
1238         
$y_axis $this->wm_vrt_offset $this->wm_padding;
1239
1240         
// Set verticle alignment
1241         
if ($this->wm_use_drop_shadow == FALSE) {
1242             
$this->wm_shadow_distance 0;
1243         }
1244         
$this->wm_vrt_alignment strtoupper(substr($this->wm_vrt_alignment01));
1245         
$this->wm_hor_alignment strtoupper(substr($this->wm_hor_alignment01));
1246
1247         switch (
$this->wm_vrt_alignment) {
1248             case  
"T" :
1249                 break;
1250             
1251             case 
"M":    
1252                 
$y_axis += ($this->orig_height/2)+($fontheight/2);
1253                 break;
1254             
1255             case 
"B":    
1256                 
$y_axis += ($this->orig_height $fontheight $this->wm_shadow_distance - ($fontheight/2));
1257                 break;
1258         }
1259
1260         
$x_shad $x_axis $this->wm_shadow_distance;
1261         
$y_shad $y_axis $this->wm_shadow_distance;
1262
1263         
// Set horizontal alignment
1264         
switch ($this->wm_hor_alignment) {
1265             case 
"L":
1266                 break;
1267             
1268             case 
"R":
1269                 if (
$this->wm_use_drop_shadow) {
1270                     
$x_shad += ($this->orig_width $fontwidth*strlen($this->wm_text));
1271                 }
1272                 
$x_axis += ($this->orig_width $fontwidth*strlen($this->wm_text));
1273                 break;
1274             
1275             case 
"C":
1276                 if (
$this->wm_use_drop_shadow) {
1277                     
$x_shad += floor(($this->orig_width $fontwidth*strlen($this->wm_text))/2);
1278                 }
1279                 
$x_axis += floor(($this->orig_width  -$fontwidth*strlen($this->wm_text))/2);
1280                 break;
1281         }
1282
1283         
//  Add the text to the source image
1284         
if ($this->wm_use_truetype) {
1285             if (
$this->wm_use_drop_shadow) {
1286                 
imagettftext($src_img$this->wm_font_size0$x_shad$y_shad$drp_color$this->wm_font_path$this->wm_text);
1287             }
1288             
imagettftext($src_img$this->wm_font_size0$x_axis$y_axis$txt_color$this->wm_font_path$this->wm_text);
1289         } else {
1290             if (
$this->wm_use_drop_shadow) {
1291                 
imagestring($src_img$this->wm_font_size$x_shad$y_shad$this->wm_text$drp_color);
1292             }
1293             
imagestring($src_img$this->wm_font_size$x_axis$y_axis$this->wm_text$txt_color);
1294         }
1295
1296         
//  Output the final image
1297         
if ($this->dynamic_output == TRUE) {
1298             
$this->_image_display_gd($src_img);
1299         } else {
1300             
$this->_image_save_gd($src_img);
1301         }
1302
1303         
imagedestroy($src_img);
1304
1305         return 
TRUE;
1306     }
1307
1308
1309     
/**
1310      * Create Image - GD
1311      *
1312      * This simply creates an image resource handle
1313      * based on the type of image being processed
1314      *
1315      * @param    string
1316      * @return    resource
1317      */
1318     
private function _image_create_gd($path ''$image_type '') {
1319         if (
$path == '') {
1320             
$path $this->full_src_path;
1321         }
1322         
1323         if (
$image_type == '') {
1324             
$image_type $this->image_type;
1325         }
1326
1327         switch (
$image_type) {
1328             case 
:
1329                 if ( ! 
function_exists('imagecreatefromgif')) {
1330                     
$this->_set_error(array('unsupported_imagecreate''gif_not_supported'));
1331                     return 
FALSE;
1332                 }
1333
1334                 return 
imagecreatefromgif($path);
1335                 break;
1336             
1337             case 
:
1338                 if ( ! 
function_exists('imagecreatefromjpeg')) {
1339                     
$this->_set_error(array('unsupported_imagecreate''jpg_not_supported'));
1340                     return 
FALSE;
1341                 }
1342
1343                 return 
imagecreatefromjpeg($path);
1344                 break;
1345             
1346             case 
:
1347                 if ( ! 
function_exists('imagecreatefrompng')) {
1348                     
$this->_set_error(array('unsupported_imagecreate''png_not_supported'));
1349                     return 
FALSE;
1350                 }
1351
1352                 return 
imagecreatefrompng($path);
1353                 break;
1354
1355         }
1356
1357         
$this->_set_error(array('unsupported_imagecreate'));
1358         return 
FALSE;
1359     }
1360
1361
1362     
/**
1363      * Write image file to disk - GD
1364      *
1365      * Takes an image resource as input and writes the file
1366      * to the specified destination
1367      *
1368      * @param    resource
1369      * @return    bool
1370      */
1371     
private function _image_save_gd($resource) {
1372         switch (
$this->image_type) {
1373             case 
:
1374                 if ( ! 
function_exists('imagegif')) {
1375                     
$this->_set_error(array('unsupported_imagecreate''gif_not_supported'));
1376                     return 
FALSE;
1377                 }
1378
1379                 if ( ! @
imagegif($resource$this->full_dst_path)) {
1380                     
$this->_set_error('save_failed');
1381                     return 
FALSE;
1382                 }
1383                 break;
1384             
1385             case 
:
1386                 if ( ! 
function_exists('imagejpeg')) {
1387                     
$this->_set_error(array('unsupported_imagecreate''jpg_not_supported'));
1388                     return 
FALSE;
1389                 }
1390
1391                 if ( ! @
imagejpeg($resource$this->full_dst_path$this->quality)) {
1392                     
$this->_set_error('save_failed');
1393                     return 
FALSE;
1394                 }
1395                 break;
1396             
1397             case 
:
1398                 if ( ! 
function_exists('imagepng')) {
1399                     
$this->_set_error(array('unsupported_imagecreate''png_not_supported'));
1400                     return 
FALSE;
1401                 }
1402
1403                 if ( ! @
imagepng($resource$this->full_dst_path)) {
1404                     
$this->_set_error('save_failed');
1405                     return 
FALSE;
1406                 }
1407                 break;
1408             
1409             default    :
1410                 
$this->_set_error(array('unsupported_imagecreate'));
1411                 return 
FALSE;
1412                 break;
1413         }
1414
1415         return 
TRUE;
1416     }
1417
1418
1419     
/**
1420      * Dynamically outputs an image
1421      *
1422      * @param    resource
1423      * @return    void
1424      */
1425     
private function _image_display_gd($resource) {
1426         
header("Content-Disposition: filename={$this->source_image};");
1427         
header("Content-Type: {$this->mime_type}");
1428         
header('Content-Transfer-Encoding: binary');
1429         
header('Last-Modified: '.gmdate('D, d M Y H:i:s'time()).' GMT');
1430
1431         switch (
$this->image_type) {
1432             case 
:    
1433                 
imagegif($resource);
1434                 break;
1435             
1436             case 
:    
1437                 
imagejpeg($resource''$this->quality);
1438                 break;
1439             
1440             case 
:    
1441                 
imagepng($resource);
1442                 break;
1443             
1444             default :    
1445                 echo 
'Unable to display the image';
1446                 break;
1447         }
1448     }
1449
1450
1451     
/**
1452      * Re-proportion Image Width/Height
1453      *
1454      * When creating thumbs, the desired width/height
1455      * can end up warping the image due to an incorrect
1456      * ratio between the full-sized image and the thumb.
1457      *
1458      * This function lets us re-proportion the width/height
1459      * if users choose to maintain the aspect ratio when resizing.
1460      *
1461      * @return    void
1462      */
1463     
private function _image_reproportion() {
1464         if ( ! 
is_numeric($this->width) || ! is_numeric($this->height) || $this->width == || $this->height == 0) {
1465             return;
1466         }
1467         
1468         if ( ! 
is_numeric($this->orig_width) || ! is_numeric($this->orig_height) || $this->orig_width == || $this->orig_height == 0) {
1469             return;
1470         }
1471         
1472         
$new_width ceil($this->orig_width*$this->height/$this->orig_height);
1473         
$new_height    ceil($this->width*$this->orig_height/$this->orig_width);
1474
1475         
$ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));
1476
1477         if (
$this->master_dim != 'width' && $this->master_dim != 'height') {
1478             
$this->master_dim = ($ratio 0) ? 'width' 'height';
1479         }
1480
1481         if ((
$this->width != $new_width) && ($this->height != $new_height)) {
1482             if (
$this->master_dim == 'height') {
1483                 
$this->width $new_width;
1484             } else {
1485                 
$this->height $new_height;
1486             }
1487         }
1488     }
1489
1490
1491     
/**
1492      * Get image properties
1493      *
1494      * A helper function that gets info about the file
1495      *
1496      * @param    string
1497      * @return    mixed
1498      */
1499     
private function _get_image_properties($path ''$return FALSE) {
1500         
// For now we require GD but we should
1501         // find a way to determine this using IM or NetPBM
1502
1503         
if ($path == '') {
1504             
$path $this->full_src_path;
1505         }
1506         
1507         if ( ! 
file_exists($path)) {
1508             
$this->_set_error('invalid_path');
1509             return 
FALSE;
1510         }
1511
1512         
$vals = @getimagesize($path);
1513
1514         
$types = array(=> 'gif'=> 'jpeg'=> 'png');
1515
1516         
$mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg';
1517
1518         if (
$return == TRUE) {
1519             
$v['width'] = $vals['0'];
1520             
$v['height'] = $vals['1'];
1521             
$v['image_type'] = $vals['2'];
1522             
$v['size_str'] = $vals['3'];
1523             
$v['mime_type'] = $mime;
1524
1525             return 
$v;
1526         }
1527
1528         
$this->orig_width $vals['0'];
1529         
$this->orig_height $vals['1'];
1530         
$this->image_type $vals['2'];
1531         
$this->size_str $vals['3'];
1532         
$this->mime_type $mime;
1533
1534         return 
TRUE;
1535     }
1536
1537
1538     
/**
1539      * Size calculator
1540      *
1541      * This function takes a known width x height and
1542      * recalculates it to a new size.  Only one
1543      * new variable needs to be known
1544      *
1545      *    $props = array(
1546      *                    'width'            => $width,
1547      *                    'height'        => $height,
1548      *                    'new_width'        => 40,
1549      *                    'new_height'    => ''
1550      *                  );
1551      *
1552      * @param    array
1553      * @return    array
1554      */
1555     
private function size_calculator($vals) {
1556         if ( ! 
is_array($vals)) {
1557             return;
1558         }
1559
1560         
$allowed = array('new_width''new_height''width''height');
1561
1562         foreach (
$allowed as $item) {
1563             if ( ! isset(
$vals[$item]) || $vals[$item] == '') {
1564                 
$vals[$item] = 0;
1565             }
1566         }
1567
1568         if (
$vals['width'] == || $vals['height'] == 0) {
1569             return 
$vals;
1570         }
1571
1572         if (
$vals['new_width'] == 0) {
1573             
$vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
1574         } elseif (
$vals['new_height'] == 0) {
1575             
$vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
1576         }
1577
1578         return 
$vals;
1579     }
1580
1581
1582     
/**
1583      * Explode source_image
1584      *
1585      * This is a helper function that extracts the extension
1586      * from the source_image.  This function lets us deal with
1587      * source_images with multiple periods, like:  my.cool.jpg
1588      * It returns an associative array with two elements:
1589      * $array['ext']  = '.jpg';
1590      * $array['name'] = 'my.cool';
1591      *
1592      * @param    array
1593      * @return    array
1594      */
1595     
private function _explode_name($source_image) {
1596         
$ext strrchr($source_image'.');
1597         
$name = ($ext === FALSE) ? $source_image substr($source_image0, -strlen($ext));
1598
1599         return array(
'ext' => $ext'name' => $name);
1600     }
1601
1602
1603     
/**
1604      * Is GD Installed?
1605      *
1606      * @return    bool
1607      */
1608     
private function gd_loaded() {
1609         if ( ! 
extension_loaded('gd')) {
1610             
// Note: dl() has been removed from some SAPI's in PHP 5.3.
1611             
if ( ! dl('gd.so')) {
1612                 return 
FALSE;
1613             }
1614         }
1615
1616         return 
TRUE;
1617     }
1618
1619     
1620     
/**
1621      * Get GD version
1622      *
1623      * @return    mixed
1624      */
1625     
private function _gd_version() {
1626         if (
function_exists('gd_info')) {
1627             
$gd_version = @gd_info();
1628             
$gd_version preg_replace("/\D/"""$gd_version['GD Version']);
1629
1630             return 
$gd_version;
1631         }
1632
1633         return 
FALSE;
1634     }
1635
1636
1637     
/**
1638      * Set error message
1639      *
1640      * @param    string
1641      * @return    void
1642      */
1643     
private function _set_error($msg) {
1644         if (
is_array($msg)) {
1645             foreach (
$msg as $val) {
1646                 
$this->_error_msg_to_display[] = isset($this->_error_messages[$val]) ? $this->_error_messages[$val] : $val;
1647             }
1648         } else {
1649             
$this->_error_msg_to_display[] = isset($this->_error_messages[$msg]) ? $this->_error_messages[$msg] : $msg;
1650         }
1651     }
1652
1653
1654     
/**
1655      * Show error messages
1656      *
1657      * @param    string
1658      * @return    string
1659      */
1660     
public function display_errors($open '<p>'$close '</p>') {
1661         
$str '';
1662         foreach (
$this->_error_msg_to_display as $val) {
1663             
$str .= $open.$val.$close;
1664         }
1665
1666         return 
$str;
1667     }
1668
1669 }
1670
1671
/* End of file: ./system/libraries/image/image_library.php */

Page URI: http://www.infopotato.com/index.php/code/library/image/