source: trunk/plugins/ImageManager/Classes/Transform.php @ 709

Last change on this file since 709 was 709, checked in by ray, 12 years ago

Ticket #928 ImageManager? fails if (another) Files.php exists in include path

  • Property svn:keywords set to LastChangedDate LastChangedRevision LastChangedBy HeadURL Id
File size: 15.8 KB
Line 
1<?php
2/***********************************************************************
3** Title.........:  Image Transformation Interface
4** Version.......:  1.0
5** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
6** Filename......:  Transform.php
7** Last changed..:  30 Aug 2003
8** Notes.........:  Orginal is from PEAR
9                   
10                    Added a few extra,
11                        - create unique filename in a particular directory,
12                          used for temp image files.
13                        - added cropping to GD, NetPBM, ImageMagick
14**/
15
16// +----------------------------------------------------------------------+
17// | PHP Version 4                                                        |
18// +----------------------------------------------------------------------+
19// | Copyright (c) 1997-2002 The PHP Group                                |
20// +----------------------------------------------------------------------+
21// | This source file is subject to version 2.02 of the PHP license,      |
22// | that is bundled with this package in the file LICENSE, and is        |
23// | available at through the world-wide-web at                           |
24// | http://www.php.net/license/2_02.txt.                                 |
25// | If you did not receive a copy of the PHP license and are unable to   |
26// | obtain it through the world-wide-web, please send a note to          |
27// | license@php.net so we can mail you a copy immediately.               |
28// +----------------------------------------------------------------------+
29// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
30// |          Alan Knowles <alan@akbkhome.com>                            |
31// |          Vincent Oostindie <vincent@sunlight.tmfweb.nl>              |
32// +----------------------------------------------------------------------+
33//
34// $Id$
35//
36// Image Transformation interface
37//
38
39
40/**
41 * The main "Image_Resize" class is a container and base class which
42 * provides the static methods for creating Image objects as well as
43 * some utility functions (maths) common to all parts of Image Resize.
44 *
45 * The object model of DB is as follows (indentation means inheritance):
46 *
47 * Image_Resize The base for each Image implementation.  Provides default
48 * |            implementations (in OO lingo virtual methods) for
49 * |            the actual Image implementations as well as a bunch of
50 * |            maths methods.
51 * |
52 * +-Image_GD   The Image implementation for the PHP GD extension .  Inherits
53 *              Image_Resize
54 *              When calling DB::setup for GD images the object returned is an
55 *              instance of this class.
56 *
57 * @package  Image Resize
58 * @version  1.00
59 * @author   Peter Bowyer <peter@mapledesign.co.uk>
60 * @since    PHP 4.0
61 */
62Class Image_Transform
63{
64    /**
65     * Name of the image file
66     * @var string
67     */
68    var $image = '';
69    /**
70     * Type of the image file (eg. jpg, gif png ...)
71     * @var string
72     */
73    var $type = '';
74    /**
75     * Original image width in x direction
76     * @var int
77     */
78    var $img_x = '';
79    /**
80     * Original image width in y direction
81     * @var int
82     */
83    var $img_y = '';
84    /**
85     * New image width in x direction
86     * @var int
87     */
88    var $new_x = '';
89    /**
90     * New image width in y direction
91     * @var int
92     */
93    var $new_y = '';
94    /**
95     * Path the the library used
96     * e.g. /usr/local/ImageMagick/bin/ or
97     * /usr/local/netpbm/
98     */
99    var $lib_path = '';
100    /**
101     * Flag to warn if image has been resized more than once before displaying
102     * or saving.
103     */
104     var $resized = false;
105
106
107     var $uid = '';
108
109     var $lapse_time =900; //15 mins
110
111    /**
112     * Create a new Image_resize object
113     *
114     * @param string $driver name of driver class to initialize
115     *
116     * @return mixed a newly created Image_Transform object, or a PEAR
117     * error object on error
118     *
119     * @see PEAR::isError()
120     * @see Image_Transform::setOption()
121     */
122    function &factory($driver)
123    {
124        if ('' == $driver) {
125            die("No image library specified... aborting.  You must call ::factory() with one parameter, the library to load.");
126
127        }
128        $this->uid = md5($_SERVER['REMOTE_ADDR']);
129
130        include_once "../ImageManager/Classes/$driver.php";
131
132        $classname = "Image_Transform_Driver_{$driver}";
133        $obj =& new $classname;
134        return $obj;
135    }
136
137
138    /**
139     * Resize the Image in the X and/or Y direction
140     * If either is 0 it will be scaled proportionally
141     *
142     * @access public
143     *
144     * @param mixed $new_x (0, number, percentage 10% or 0.1)
145     * @param mixed $new_y (0, number, percentage 10% or 0.1)
146     *
147     * @return mixed none or PEAR_error
148     */
149    function resize($new_x = 0, $new_y = 0)
150    {
151        // 0 means keep original size
152        $new_x = (0 == $new_x) ? $this->img_x : $this->_parse_size($new_x, $this->img_x);
153        $new_y = (0 == $new_y) ? $this->img_y : $this->_parse_size($new_y, $this->img_y);
154        // Now do the library specific resizing.
155        return $this->_resize($new_x, $new_y);
156    } // End resize
157
158
159    /**
160     * Scale the image to have the max x dimension specified.
161     *
162     * @param int $new_x Size to scale X-dimension to
163     * @return none
164     */
165    function scaleMaxX($new_x)
166    {
167        $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
168        return $this->_resize($new_x, $new_y);
169    } // End resizeX
170
171    /**
172     * Scale the image to have the max y dimension specified.
173     *
174     * @access public
175     * @param int $new_y Size to scale Y-dimension to
176     * @return none
177     */
178    function scaleMaxY($new_y)
179    {
180        $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
181        return $this->_resize($new_x, $new_y);
182    } // End resizeY
183
184    /**
185     * Scale Image to a maximum or percentage
186     *
187     * @access public
188     * @param mixed (number, percentage 10% or 0.1)
189     * @return mixed none or PEAR_error
190     */
191    function scale($size)
192    {
193        if ((strlen($size) > 1) && (substr($size,-1) == '%')) {
194            return $this->scaleByPercentage(substr($size, 0, -1));
195        } elseif ($size < 1) {
196            return $this->scaleByFactor($size);
197        } else {
198            return $this->scaleByLength($size);
199        }
200    } // End scale
201
202    /**
203     * Scales an image to a percentage of its original size.  For example, if
204     * my image was 640x480 and I called scaleByPercentage(10) then the image
205     * would be resized to 64x48
206     *
207     * @access public
208     * @param int $size Percentage of original size to scale to
209     * @return none
210     */
211    function scaleByPercentage($size)
212    {
213        return $this->scaleByFactor($size / 100);
214    } // End scaleByPercentage
215
216    /**
217     * Scales an image to a factor of its original size.  For example, if
218     * my image was 640x480 and I called scaleByFactor(0.5) then the image
219     * would be resized to 320x240.
220     *
221     * @access public
222     * @param float $size Factor of original size to scale to
223     * @return none
224     */
225    function scaleByFactor($size)
226    {
227        $new_x = round($size * $this->img_x, 0);
228        $new_y = round($size * $this->img_y, 0);
229        return $this->_resize($new_x, $new_y);
230    } // End scaleByFactor
231
232    /**
233     * Scales an image so that the longest side has this dimension.
234     *
235     * @access public
236     * @param int $size Max dimension in pixels
237     * @return none
238     */
239    function scaleByLength($size)
240    {
241         if ($this->img_x >= $this->img_y) {
242            $new_x = $size;
243            $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
244        } else {
245            $new_y = $size;
246            $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
247        }
248        return $this->_resize($new_x, $new_y);
249    } // End scaleByLength
250
251
252    /**
253     *
254     * @access public
255     * @return void
256     */
257    function _get_image_details($image)
258    {
259        //echo $image;
260        $data = @GetImageSize($image);
261        #1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte order,
262        # 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC
263        if (is_array($data)){
264            switch($data[2]){
265                case 1:
266                    $type = 'gif';
267                    break;
268                case 2:
269                    $type = 'jpeg';
270                    break;
271                case 3:
272                    $type = 'png';
273                    break;
274                case 4:
275                    $type = 'swf';
276                    break;
277                case 5:
278                    $type = 'psd';
279                case 6:
280                    $type = 'bmp';
281                case 7:
282                case 8:
283                    $type = 'tiff';
284                default:
285                    echo("We do not recognize this image format");
286            }
287            $this->img_x = $data[0];
288            $this->img_y = $data[1];
289            $this->type = $type;
290
291            return true;
292        } else {
293            echo("Cannot fetch image or images details.");
294            return null;
295        }
296        /*
297        $output = array(
298                        'width' => $data[0],
299                        'height' => $data[1],
300                        'type' => $type
301                        );
302        return $output;
303        */
304    }
305
306
307    /**
308     * Parse input and convert
309     * If either is 0 it will be scaled proportionally
310     *
311     * @access private
312     *
313     * @param mixed $new_size (0, number, percentage 10% or 0.1)
314     * @param int $old_size
315     *
316     * @return mixed none or PEAR_error
317     */
318    function _parse_size($new_size, $old_size)
319    {
320        if ('%' == $new_size) {
321            $new_size = str_replace('%','',$new_size);
322            $new_size = $new_size / 100;
323        }
324        if ($new_size > 1) {
325            return (int) $new_size;
326        } elseif ($new_size == 0) {
327            return (int) $old_size;
328        } else {
329            return (int) round($new_size * $old_size, 0);
330        }
331    }
332
333
334    function uniqueStr()
335    {
336      return substr(md5(microtime()),0,6);
337    }
338
339    //delete old tmp files, and allow only 1 file per remote host.
340    function cleanUp($id, $dir)
341    {
342        $d = dir($dir);
343        $id_length = strlen($id);
344
345        while (false !== ($entry = $d->read())) {
346            if (is_file($dir.'/'.$entry) && substr($entry,0,1) == '.' && !ereg($entry, $this->image))
347            {
348                //echo filemtime($this->directory.'/'.$entry)."<br>";
349                //echo time();
350
351                if (filemtime($dir.'/'.$entry) + $this->lapse_time < time())
352                    unlink($dir.'/'.$entry);
353
354                if (substr($entry, 1, $id_length) == $id)
355                {
356                    if (is_file($dir.'/'.$entry))
357                        unlink($dir.'/'.$entry);
358                }
359            }
360        }
361        $d->close();
362    }
363
364
365    function createUnique($dir)
366    {
367       $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
368       
369       //make sure the the unique temp file does not exists
370        while (file_exists($dir.$unique_str))
371        {
372            $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
373        }
374       
375      $this->cleanUp($this->uid, $dir);
376
377       return $unique_str;
378    }
379
380
381    /**
382     * Set the image width
383     * @param int $size dimension to set
384     * @since 29/05/02 13:36:31
385     * @return
386     */
387    function _set_img_x($size)
388    {
389        $this->img_x = $size;
390    }
391
392    /**
393     * Set the image height
394     * @param int $size dimension to set
395     * @since 29/05/02 13:36:31
396     * @return
397     */
398    function _set_img_y($size)
399    {
400        $this->img_y = $size;
401    }
402
403    /**
404     * Set the image width
405     * @param int $size dimension to set
406     * @since 29/05/02 13:36:31
407     * @return
408     */
409    function _set_new_x($size)
410    {
411        $this->new_x = $size;
412    }
413
414    /**
415     * Set the image height
416     * @param int $size dimension to set
417     * @since 29/05/02 13:36:31
418     * @return
419     */
420    function _set_new_y($size)
421    {
422        $this->new_y = $size;
423    }
424
425    /**
426     * Get the type of the image being manipulated
427     *
428     * @return string $this->type the image type
429     */
430    function getImageType()
431    {
432        return $this->type;
433    }
434
435    /**
436     *
437     * @access public
438     * @return string web-safe image type
439     */
440    function getWebSafeFormat()
441    {
442        switch($this->type){
443            case 'gif':
444            case 'png':
445                return 'png';
446                break;
447            default:
448                return 'jpeg';
449        } // switch
450    }
451
452    /**
453     * Place holder for the real resize method
454     * used by extended methods to do the resizing
455     *
456     * @access private
457     * @return PEAR_error
458     */
459    function _resize() {
460        return null; //PEAR::raiseError("No Resize method exists", true);
461    }
462
463    /**
464     * Place holder for the real load method
465     * used by extended methods to do the resizing
466     *
467     * @access public
468     * @return PEAR_error
469     */
470    function load($filename) {
471        return null; //PEAR::raiseError("No Load method exists", true);
472    }
473
474    /**
475     * Place holder for the real display method
476     * used by extended methods to do the resizing
477     *
478     * @access public
479     * @param string filename
480     * @return PEAR_error
481     */
482    function display($type, $quality) {
483        return null; //PEAR::raiseError("No Display method exists", true);
484    }
485
486    /**
487     * Place holder for the real save method
488     * used by extended methods to do the resizing
489     *
490     * @access public
491     * @param string filename
492     * @return PEAR_error
493     */
494    function save($filename, $type, $quality) {
495        return null; //PEAR::raiseError("No Save method exists", true);
496    }
497
498    /**
499     * Place holder for the real free method
500     * used by extended methods to do the resizing
501     *
502     * @access public
503     * @return PEAR_error
504     */
505    function free() {
506        return null; //PEAR::raiseError("No Free method exists", true);
507    }
508
509    /**
510     * Reverse of rgb2colorname.
511     *
512     * @access public
513     * @return PEAR_error
514     *
515     * @see rgb2colorname
516     */
517    function colorhex2colorarray($colorhex) {
518        $r = hexdec(substr($colorhex, 1, 2));
519        $g = hexdec(substr($colorhex, 3, 2));
520        $b = hexdec(substr($colorhex, 4, 2));
521        return array($r,$g,$b);
522    }
523
524    /**
525     * Reverse of rgb2colorname.
526     *
527     * @access public
528     * @return PEAR_error
529     *
530     * @see rgb2colorname
531     */
532    function colorarray2colorhex($color) {
533        $color = '#'.dechex($color[0]).dechex($color[1]).dechex($color[2]);
534        return strlen($color)>6?false:$color;
535    }
536
537
538    /* Methods to add to the driver classes in the future */
539    function addText()
540    {
541        return null; //PEAR::raiseError("No addText method exists", true);
542    }
543
544    function addDropShadow()
545    {
546        return null; //PEAR::raiseError("No AddDropShadow method exists", true);
547    }
548
549    function addBorder()
550    {
551        return null; //PEAR::raiseError("No addBorder method exists", true);
552    }
553
554    function crop()
555    {
556        return null; //PEAR::raiseError("No crop method exists", true);
557    }
558
559    function flip()
560    {
561        return null;
562    }
563
564    function gamma()
565    {
566        return null; //PEAR::raiseError("No gamma method exists", true);
567    }
568}
569?>
Note: See TracBrowser for help on using the repository browser.