source: branches/1.2/workflow/js/htmlarea/plugins/UploadImage/popups/ImageEditor/GD.php @ 1349

Revision 1349, 16.1 KB checked in by niltonneto, 15 years ago (diff)

Ticket #561 - Inclusão do módulo Workflow faltante nessa versão.

  • Property svn:executable set to *
Line 
1<?php
2/***********************************************************************
3** Title.........:  GD Driver
4** Version.......:  1.0
5** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
6** Filename......:  GD.php
7** Last changed..:  30 Aug 2003
8** Notes.........:  Orginal is from PEAR
9**/
10// +----------------------------------------------------------------------+
11// | PHP Version 4                                                        |
12// +----------------------------------------------------------------------+
13// | Copyright (c) 1997-2002 The PHP Group                                |
14// +----------------------------------------------------------------------+
15// | This source file is subject to version 2.02 of the PHP license,      |
16// | that is bundled with this package in the file LICENSE, and is        |
17// | available at through the world-wide-web at                           |
18// | http://www.php.net/license/2_02.txt.                                 |
19// | If you did not receive a copy of the PHP license and are unable to   |
20// | obtain it through the world-wide-web, please send a note to          |
21// | license@php.net so we can mail you a copy immediately.               |
22// +----------------------------------------------------------------------+
23// | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
24// |          Alan Knowles <alan@akbkhome.com>                            |
25// +----------------------------------------------------------------------+
26//
27//    Usage :
28//    $img    = new Image_Transform_GD();
29//    $angle  = -78;
30//    $img->load('magick.png');
31//
32//    if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
33//        $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
34//        $img->display();
35//    } else {
36//        echo "Error";
37//    }
38//
39//
40//
41// Image Transformation interface using the GD library
42//
43
44require_once "Transform.php";
45
46Class Image_Transform_Driver_GD extends Image_Transform
47{
48    /**
49     * Holds the image file for manipulation
50     */
51    var $imageHandle = '';
52
53    /**
54     * Holds the original image file
55     */
56    var $old_image = '';
57
58    /**
59     * Check settings
60     *
61     * @return mixed true or  or a PEAR error object on error
62     *
63     * @see PEAR::isError()
64     */
65    function Image_Transform_GD()
66    {
67        return;
68    } // End function Image
69
70    /**
71     * Load image
72     *
73     * @param string filename
74     *
75     * @return mixed none or a PEAR error object on error
76     * @see PEAR::isError()
77     */
78    function load($image)
79    {
80        $this->uid = md5($_SERVER['REMOTE_ADDR']);
81                $this->image = $image;
82        $this->_get_image_details($image);
83        $functionName = 'ImageCreateFrom' . $this->type;
84        $this->imageHandle = $functionName($this->image);
85    } // End load
86
87    /**
88     * addText
89     *
90     * @param   array   options     Array contains options
91     *                              array(
92     *                                  'text'  The string to draw
93     *                                  'x'     Horizontal position
94     *                                  'y'     Vertical Position
95     *                                  'Color' Font color
96     *                                  'font'  Font to be used
97     *                                  'size'  Size of the fonts in pixel
98     *                                  'resize_first'  Tell if the image has to be resized
99     *                                                  before drawing the text
100     *                              )
101     *
102     * @return none
103     * @see PEAR::isError()
104     */
105    function addText($params)
106    {
107        $default_params = array(
108                                'text' => 'This is Text',
109                                'x' => 10,
110                                'y' => 20,
111                                'color' => array(255,0,0),
112                                'font' => 'Arial.ttf',
113                                'size' => '12',
114                                'angle' => 0,
115                                'resize_first' => false // Carry out the scaling of the image before annotation?  Not used for GD
116                                );
117        $params = array_merge($default_params, $params);
118        extract($params);
119
120        if( !is_array($color) ){
121            if ($color[0]=='#'){
122                $this->colorhex2colorarray( $color );
123            } else {
124                include_once('Image/Transform/Driver/ColorsDefs.php');
125                $color = isset($colornames[$color])?$colornames[$color]:false;
126            }
127        }
128
129        $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]);
130
131        if ('ttf' == substr($font, -3)) {
132            ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
133        } else {
134            ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
135        }
136        return true;
137    } // End addText
138
139
140    /**
141     * Rotate image by the given angle
142     * Uses a fast rotation algorythm for custom angles
143     * or lines copy for multiple of 90 degrees
144     *
145     * @param int       $angle      Rotation angle
146     * @param array     $options    array(  'autoresize'=>true|false,
147     *                                      'color_mask'=>array(r,g,b), named color or #rrggbb
148     *                                   )
149     * @author Pierre-Alain Joye
150     * @return mixed none or a PEAR error object on error
151     * @see PEAR::isError()
152     */
153    function rotate($angle, $options=null)
154    {
155        if(function_exists('imagerotate')) {
156            $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
157                        $this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
158            return true;
159        }
160
161        if ( $options==null ){
162            $autoresize = true;
163            $color_mask = array(255,255,0);
164        } else {
165            extract( $options );
166        }
167
168        while ($angle <= -45) {
169            $angle  += 360;
170        }
171        while ($angle > 270) {
172            $angle  -= 360;
173        }
174
175        $t      = deg2rad($angle);
176
177        if( !is_array($color_mask) ){
178            if ($color[0]=='#'){
179                $this->colorhex2colorarray( $color_mask );
180            } else {
181                include_once('Image/Transform/Driver/ColorDefs.php');
182                $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
183            }
184        }
185
186        // Do not round it, too much lost of quality
187        $cosT   = cos($t);
188        $sinT   = sin($t);
189
190        $img    =& $this->imageHandle;
191
192        $width  = $max_x  = $this->img_x;
193        $height = $max_y  = $this->img_y;
194        $min_y  = 0;
195        $min_x  = 0;
196
197        $x1     = round($max_x/2,0);
198        $y1     = round($max_y/2,0);
199
200        if ( $autoresize ){
201            $t      = abs($t);
202            $a      = round($angle,0);
203            switch((int)($angle)){
204                case 0:
205                        $width2     = $width;
206                        $height2    = $height;
207                    break;
208                case 90:
209                        $width2     = $height;
210                        $height2    = $width;
211                    break;
212                case 180:
213                        $width2     = $width;
214                        $height2    = $height;
215                    break;
216                case 270:
217                        $width2     = $height;
218                        $height2    = $width;
219                    break;
220                default:
221                    $width2     = (int)(abs(sin($t) * $height + cos($t) * $width));
222                    $height2    = (int)(abs(cos($t) * $height+sin($t) * $width));
223            }
224
225            $width2     -= $width2%2;
226            $height2    -= $height2%2;
227
228            $d_width    = abs($width - $width2);
229            $d_height   = abs($height - $height2);
230            $x_offset   = $d_width/2;
231            $y_offset   = $d_height/2;
232            $min_x2     = -abs($x_offset);
233            $min_y2     = -abs($y_offset);
234            $max_x2     = $width2;
235            $max_y2     = $height2;
236        }
237
238        $img2   = @imagecreate($width2,$height2);
239
240        if ( !is_resource($img2) ){
241            return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
242                                null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
243        }
244
245        $this->img_x = $width2;
246        $this->img_y = $height2;
247
248
249        imagepalettecopy($img2,$img);
250
251        $mask   = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
252
253        // use simple lines copy for axes angles
254        switch((int)($angle)){
255            case 0:
256                imagefill ($img2, 0, 0,$mask);
257                for ($y=0; $y < $max_y; $y++) {
258                    for ($x = $min_x; $x < $max_x; $x++){
259                        $c  = @imagecolorat ( $img, $x, $y);
260                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
261                    }
262                }
263                break;
264            case 90:
265                imagefill ($img2, 0, 0,$mask);
266                for ($x = $min_x; $x < $max_x; $x++){
267                    for ($y=$min_y; $y < $max_y; $y++) {
268                        $c  = imagecolorat ( $img, $x, $y);
269                        imagesetpixel($img2,$max_y-$y-1,$x,$c);
270                    }
271                }
272                break;
273            case 180:
274                imagefill ($img2, 0, 0,$mask);
275                for ($y=0; $y < $max_y; $y++) {
276                    for ($x = $min_x; $x < $max_x; $x++){
277                        $c  = @imagecolorat ( $img, $x, $y);
278                        imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
279                    }
280                }
281                break;
282            case 270:
283                imagefill ($img2, 0, 0,$mask);
284                for ($y=0; $y < $max_y; $y++) {
285                    for ($x = $max_x; $x >= $min_x; $x--){
286                        $c  = @imagecolorat ( $img, $x, $y);
287                        imagesetpixel($img2,$y,$max_x-$x-1,$c);
288                    }
289                }
290                break;
291            // simple reverse rotation algo
292            default:
293                $i=0;
294                for ($y = $min_y2; $y < $max_y2; $y++){
295
296                    // Algebra :)
297                    $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
298                    $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);
299
300                    for ($x = $min_x2; $x < $max_x2; $x++){
301
302                        // Check if we are out of original bounces, if we are
303                        // use the default color mask
304                        if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
305                            $c  = imagecolorat ( $img, $x2, $y2);
306                        } else {
307                            $c  = $mask;
308                        }
309                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
310
311                        // round verboten!
312                        $x2  += $cosT;
313                        $y2  -= $sinT;
314                    }
315                }
316                break;
317        }
318        $this->old_image    = $this->imageHandle;
319        $this->imageHandle  =  $img2;
320        return true;
321    }
322
323
324   /**
325    * Resize Action
326    *
327    * For GD 2.01+ the new copyresampled function is used
328    * It uses a bicubic interpolation algorithm to get far
329    * better result.
330    *
331    * @param $new_x int  new width
332    * @param $new_y int  new height
333    *
334    * @return true on success or pear error
335    * @see PEAR::isError()
336    */
337    function _resize($new_x, $new_y) {
338        if ($this->resized === true) {
339            return false; /*PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
340        }
341        if(function_exists('ImageCreateTrueColor')){
342            $new_img =ImageCreateTrueColor($new_x,$new_y);
343        } else {
344            $new_img =ImageCreate($new_x,$new_y);
345        }
346        if(function_exists('ImageCopyResampled')){
347            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
348        } else {
349            ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
350        }
351        $this->old_image = $this->imageHandle;
352        $this->imageHandle = $new_img;
353        $this->resized = true;
354
355        $this->new_x = $new_x;
356        $this->new_y = $new_y;
357        return true;
358    }
359
360    /**
361     * Crop the image
362     *
363     * @param int $crop_x left column of the image
364     * @param int $crop_y top row of the image
365     * @param int $crop_width new cropped image width
366     * @param int $crop_height new cropped image height
367     */
368    function crop($new_x, $new_y, $new_width, $new_height)
369    {
370        if(function_exists('ImageCreateTrueColor')){
371            $new_img =ImageCreateTrueColor($new_width,$new_height);
372        } else {
373            $new_img =ImageCreate($new_width,$new_height);
374        }
375        if(function_exists('ImageCopyResampled')){
376            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height);
377        } else {
378            ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height);
379        }
380        $this->old_image = $this->imageHandle;
381        $this->imageHandle = $new_img;
382        $this->resized = true;
383
384        $this->new_x = $new_x;
385        $this->new_y = $new_y;
386        return true;
387    }
388   
389    /**
390     * Flip the image horizontally or vertically
391     *
392     * @param boolean $horizontal true if horizontal flip, vertical otherwise
393     */
394    function flip($horizontal)
395    {
396        if(!$horizontal) {
397            $this->rotate(180);
398        }
399
400        $width = imagesx($this->imageHandle);
401        $height = imagesy($this->imageHandle);
402
403        for ($j = 0; $j < $height; $j++) {
404                $left = 0;
405                $right = $width-1;
406
407
408                while ($left < $right) {
409                    //echo " j:".$j." l:".$left." r:".$right."\n<br>";
410                    $t = imagecolorat($this->imageHandle, $left, $j);
411                    imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j));
412                    imagesetpixel($this->imageHandle, $right, $j, $t);
413                    $left++; $right--;
414                }
415        }
416
417        return true;
418    }
419
420
421    /**
422     * Adjust the image gamma
423     *
424     * @param float $outputgamma
425     *
426     * @return none
427     */
428    function gamma($outputgamma=1.0) {
429        ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
430    }
431
432    /**
433     * Save the image file
434     *
435     * @param $filename string  the name of the file to write to
436     * @param $quality  int     output DPI, default is 85
437     * @param $types    string  define the output format, default
438     *                          is the current used format
439     *
440     * @return none
441     */
442    function save($filename, $type = '', $quality = 85)
443    {
444        $type           = $type==''? $this->type : $type;
445        $functionName   = 'image' . $type;
446        $this->old_image = $this->imageHandle;
447        $functionName($this->imageHandle, $filename) ;
448        $this->imageHandle = $this->old_image;
449        $this->resized = false;
450    } // End save
451
452
453    /**
454     * Display image without saving and lose changes
455     *
456     * @param string type (JPG,PNG...);
457     * @param int quality 75
458     *
459     * @return none
460     */
461    function display($type = '', $quality = 75)
462    {
463        if ($type != '') {
464            $this->type = $type;
465        }
466        $functionName = 'Image' . $this->type;
467        header('Content-type: image/' . strtolower($this->type));
468        $functionName($this->imageHandle, '', $quality);
469        $this->imageHandle = $this->old_image;
470        $this->resized = false;
471        ImageDestroy($this->old_image);
472        $this->free();
473    }
474
475    /**
476     * Destroy image handle
477     *
478     * @return none
479     */
480    function free()
481    {
482        if ($this->imageHandle){
483            ImageDestroy($this->imageHandle);
484        }
485    }
486
487} // End class ImageGD
488?>
Note: See TracBrowser for help on using the repository browser.