Passed
Push — master ( 8d8e58...047d50 )
by Michael
02:21
created

Image_Transform_Driver_GD   F

Complexity

Total Complexity 70

Size/Duplication

Total Lines 550
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 550
rs 2.7272
c 1
b 0
f 0
wmc 70

18 Methods

Rating   Name   Duplication   Size   Complexity  
A free() 0 11 3
A gamma() 0 7 2
A rotate() 0 16 2
A flip() 0 22 2
A getHandle() 0 3 1
A display() 0 3 1
C __construct() 0 23 9
C _resize() 0 32 8
A save() 0 7 2
B crop() 0 26 3
D _createImage() 0 56 12
A Image_Transform_Driver_GD() 0 3 1
A greyscale() 0 5 1
A addBorder() 0 22 3
A addText() 0 18 2
B load() 0 22 4
A mirror() 0 10 2
D _generate() 0 47 12

How to fix   Complexity   

Complex Class

Complex classes like Image_Transform_Driver_GD often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Image_Transform_Driver_GD, and based on these observations, apply Extract Interface, too.

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 65 and the first side effect is on line 29.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/* vim: set expandtab tabstop=4 shiftwidth=4: */
4
5
/**
6
 * GD implementation for Image_Transform package
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * that is available through the world-wide-web at the following URI:
12
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * the PHP License and are unable to obtain it through the web, please
14
 * send a note to [email protected] so we can mail you a copy immediately.
15
 *
16
 * @category   Image
17
 * @package    Image_Transform
18
 * @subpackage Image_Transform_Driver_GD
19
 * @author     Alan Knowles <[email protected]>
20
 * @author     Peter Bowyer <[email protected]>
21
 * @author     Philippe Jausions <[email protected]>
22
 * @copyright  2002-2005 The PHP Group
23
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
24
 * @version    CVS: $Id: GD.php 322661 2012-01-24 12:02:59Z clockwerx $
25
 * @link       http://pear.php.net/package/Image_Transform
26
 */
27
28
//require_once 'Image/Transform.php';
29
require_once XOOPS_ROOT_PATH . '/modules/extgallery/class/pear/Image/Transform.php';
0 ignored issues
show
Bug introduced by
The constant XOOPS_ROOT_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
30
31
/**
32
 * GD implementation for Image_Transform package
33
 *
34
 * Usage :
35
 *    $img    =& Image_Transform::factory('GD');
36
 *    $angle  = -78;
37
 *    $img->load('magick.png');
38
 *
39
 *    if ($img->rotate($angle, array(
40
 *               'autoresize' => true,
41
 *               'color_mask' => array(255, 0, 0)))) {
42
 *        $img->addText(array(
43
 *               'text' => 'Rotation ' . $angle,
44
 *               'x' => 0,
45
 *               'y' => 100,
46
 *               'font' => '/usr/share/fonts/default/TrueType/cogb____.ttf'));
47
 *        $img->display();
48
 *    } else {
49
 *        echo "Error";
50
 *    }
51
 *    $img->free();
52
 *
53
 * @category   Image
54
 * @package    Image_Transform
55
 * @subpackage Image_Transform_Driver_GD
56
 * @author     Alan Knowles <[email protected]>
57
 * @author     Peter Bowyer <[email protected]>
58
 * @author     Philippe Jausions <[email protected]>
59
 * @copyright  2002-2005 The PHP Group
60
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
61
 * @version    Release: @package_version@
62
 * @link       http://pear.php.net/package/Image_Transform
63
 * @since      PHP 4.0
64
 */
65
class Image_Transform_Driver_GD extends Image_Transform
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
66
{
67
    /**
68
     * Holds the image resource for manipulation
69
     *
70
     * @var resource $imageHandle
71
     * @access protected
72
     */
73
    public $imageHandle = null;
74
75
    /**
76
     * Holds the original image file
77
     *
78
     * @var resource $imageHandle
79
     * @access protected
80
     */
81
    public $oldImage = null;
82
83
    /**
84
     * Check settings
85
     */
86
    public function Image_Transform_Driver_GD()
87
    {
88
        $this->__construct();
89
    } // End function Image
90
91
    /**
92
     * Check settings
93
     *
94
     * @since PHP 5
95
     */
96
    public function __construct()
97
    {
98
        if (!PEAR::loadExtension('gd')) {
99
            $this->isError(PEAR::raiseError("GD library is not available.", IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
0 ignored issues
show
Bug introduced by
The method raiseError() does not exist on PEAR. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

99
            $this->isError(PEAR::/** @scrutinizer ignore-call */ raiseError("GD library is not available.", IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
Loading history...
100
        } else {
101
            $types = ImageTypes();
102
            if ($types & IMG_PNG) {
103
                $this->_supported_image_types['png'] = 'rw';
104
            }
105
            if (($types & IMG_GIF)
106
                || function_exists('imagegif')) {
107
                $this->_supported_image_types['gif'] = 'rw';
108
            } elseif (function_exists('imagecreatefromgif')) {
109
                $this->_supported_image_types['gif'] = 'rw';
110
            }
111
            if ($types & IMG_JPG) {
112
                $this->_supported_image_types['jpeg'] = 'rw';
113
            }
114
            if ($types & IMG_WBMP) {
115
                $this->_supported_image_types['wbmp'] = 'rw';
116
            }
117
            if (!$this->_supported_image_types) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_supported_image_types of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
118
                $this->isError(PEAR::raiseError("No supported image types available", IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
119
            }
120
        }
121
    } // End function Image
122
123
    /**
124
     * Loads an image from file
125
     *
126
     * @param string $image filename
127
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
128
     * @access public
129
     */
130
    public function load($image)
131
    {
132
        $this->free();
133
134
        $this->image = $image;
135
        $result      = $this->_get_image_details($image);
136
        if (PEAR::isError($result)) {
137
            return $result;
138
        }
139
        if (!$this->supportsType($this->type, 'r')) {
140
            return PEAR::raiseError('Image type not supported for input', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
141
        }
142
143
        $functionName      = 'ImageCreateFrom' . $this->type;
144
        $this->imageHandle = $functionName($this->image);
145
        if (!$this->imageHandle) {
146
            $this->imageHandle = null;
147
148
            return PEAR::raiseError('Error while loading image file.', IMAGE_TRANSFORM_ERROR_IO);
149
        }
150
151
        return true;
152
    } // End load
153
154
    /**
155
     * Returns the GD image handle
156
     *
157
     * @return resource
158
     *
159
     * @access public
160
     */
161
    public function getHandle()
162
    {
163
        return $this->imageHandle;
164
    }//function getHandle()
165
166
    /**
167
     * Adds a border of constant width around an image
168
     *
169
     * @param int $border_width Width of border to add
170
     * @author Peter Bowyer
171
     * @return bool TRUE
172
     * @access public
173
     */
174
    public function addBorder($border_width=null, $color = '')
175
    {
176
        $this->new_x = $this->img_x + 2 * $border_width;
177
        $this->new_y = $this->img_y + 2 * $border_width;
178
179
        $new_img = $this->_createImage($new_x, $new_y, $this->true_color);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $new_y seems to be never defined.
Loading history...
Bug Best Practice introduced by
The property true_color does not exist on Image_Transform_Driver_GD. Did you maybe forget to declare it?
Loading history...
Comprehensibility Best Practice introduced by
The variable $new_x seems to be never defined.
Loading history...
180
181
        $options = array('pencilColor', $color);
182
        $color   = $this->_getColor('pencilColor', $options, array(0, 0, 0));
183
        if ($color) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $color of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
184
            if ($this->true_color) {
185
                $c = imagecolorresolve($this->imageHandle, $color[0], $color[1], $color[2]);
186
                imagefill($new_img, 0, 0, $c);
187
            } else {
188
                imagecolorset($new_img, imagecolorat($new_img, 0, 0), $color[0], $color[1], $color[2]);
189
            }
190
        }
191
        ImageCopy($new_img, $this->imageHandle, $border_width, $border_width, 0, 0, $this->img_x, $this->img_y);
192
        $this->imageHandle = $new_img;
193
        $this->resized     = true;
194
195
        return true;
196
    }
197
198
    /**
199
     * addText
200
     *
201
     * @param   array $params                           Array contains options
202
     *                                                  array(
203
     *                                                  'text'  The string to draw
204
     *                                                  'x'     Horizontal position
205
     *                                                  'y'     Vertical Position
206
     *                                                  'color' Font color
207
     *                                                  'font'  Font to be used
208
     *                                                  'size'  Size of the fonts in pixel
209
     *                                                  'resize_first'  Tell if the image has to be resized
210
     *                                                  before drawing the text
211
     *                                                  )
212
     *
213
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
214
     */
215
    public function addText($params=null)
216
    {
217
        $this->oldImage = $this->imageHandle;
218
        $params         = array_merge($this->_get_default_text_params(), $params);
219
        extract($params);
220
221
        $options = array('fontColor' => $color);
222
        $color   = $this->_getColor('fontColor', $options, array(0, 0, 0));
223
224
        $c = imagecolorresolve($this->imageHandle, $color[0], $color[1], $color[2]);
225
226
        if ('ttf' == substr($font, -3)) {
227
            ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
228
        } else {
229
            ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
230
        }
231
232
        return true;
233
    } // End addText
234
235
    /**
236
     * Rotates image by the given angle
237
     *
238
     * Uses a fast rotation algorythm for custom angles
239
     * or lines copy for multiple of 90 degrees
240
     *
241
     * @param int   $angle         Rotation angle
242
     * @param array $options       array(
243
     *                             'canvasColor' => array(r ,g, b), named color or #rrggbb
244
     *                             )
245
     * @author Pierre-Alain Joye
246
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
247
     * @access public
248
     */
249
    public function rotate($angle, $options = null)
250
    {
251
        if (0 == ($angle % 360)) {
252
            return true;
253
        }
254
255
        $color_mask = $this->_getColor('canvasColor', $options, array(255, 255, 255));
256
257
        $mask = imagecolorresolve($this->imageHandle, $color_mask[0], $color_mask[1], $color_mask[2]);
258
259
        $this->oldImage = $this->imageHandle;
260
261
        // Multiply by -1 to change the sign, so the image is rotated clockwise
262
        $this->imageHandle = ImageRotate($this->imageHandle, $angle * -1, $mask);
263
264
        return true;
265
    }
266
267
    /**
268
     * Horizontal mirroring
269
     *
270
     * @return mixed TRUE or PEAR_Error object on error
271
     * @access public
272
     * @see    flip()
273
     **/
274
    public function mirror()
275
    {
276
        $new_img = $this->_createImage();
277
        for ($x = 0; $x < $this->new_x; ++$x) {
278
            imagecopy($new_img, $this->imageHandle, $x, 0, $this->new_x - $x - 1, 0, 1, $this->new_y);
279
        }
280
        imagedestroy($this->imageHandle);
281
        $this->imageHandle = $new_img;
282
283
        return true;
284
    }
285
286
    /**
287
     * Vertical mirroring
288
     *
289
     * @return TRUE or PEAR Error object on error
290
     * @access public
291
     * @see    mirror()
292
     **/
293
    public function flip()
294
    {
295
        $new_img = $this->_createImage();
296
        for ($y = 0; $y < $this->new_y; ++$y) {
297
            imagecopy($new_img, $this->imageHandle, 0, $y, 0, $this->new_y - $y - 1, $this->new_x, 1);
298
        }
299
        imagedestroy($this->imageHandle);
300
        $this->imageHandle = $new_img;
301
302
        /* for very large images we may want to use the following
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
303
           Needs to find out what is the threshhold
304
        for ($x = 0; $x < $this->new_x; ++$x) {
305
            for ($y1 = 0; $y1 < $this->new_y / 2; ++$y1) {
306
                $y2 = $this->new_y - 1 - $y1;
307
                $color1 = imagecolorat($this->imageHandle, $x, $y1);
308
                $color2 = imagecolorat($this->imageHandle, $x, $y2);
309
                imagesetpixel($this->imageHandle, $x, $y1, $color2);
310
                imagesetpixel($this->imageHandle, $x, $y2, $color1);
311
            }
312
        } */
313
314
        return true;
315
    }
316
317
    /**
318
     * Crops image by size and start coordinates
0 ignored issues
show
Bug introduced by
The type y was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
319
     *
320
     * @param int width Cropped image width
321
     * @param int height Cropped image height
322
     * @param int x X-coordinate to crop at
323
     * @param int y Y-coordinate to crop at
324
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
325
     * @access public
326
     */
327
    public function crop($width, $height, $x = 0, $y = 0)
328
    {
329
        // Sanity check
330
        if (!$this->intersects($width, $height, $x, $y)) {
331
            return PEAR::raiseError('Nothing to crop', IMAGE_TRANSFORM_ERROR_OUTOFBOUND);
332
        }
333
        $x       = min($this->new_x, max(0, $x));
334
        $y       = min($this->new_y, max(0, $y));
335
        $width   = min($width, $this->new_x - $x);
336
        $height  = min($height, $this->new_y - $y);
337
        $new_img = $this->_createImage($width, $height);
338
339
        if (!imagecopy($new_img, $this->imageHandle, 0, 0, $x, $y, $width, $height)) {
340
            imagedestroy($new_img);
341
342
            return PEAR::raiseError('Failed transformation: crop()', IMAGE_TRANSFORM_ERROR_FAILED);
343
        }
344
345
        $this->oldImage    = $this->imageHandle;
346
        $this->imageHandle = $new_img;
347
        $this->resized     = true;
348
349
        $this->new_x = $width;
350
        $this->new_y = $height;
351
352
        return true;
353
    }
354
355
    /**
356
     * Converts the image to greyscale
357
     *
358
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
359
     * @access public
360
     */
361
    public function greyscale()
362
    {
363
        imagecopymergegray($this->imageHandle, $this->imageHandle, 0, 0, 0, 0, $this->new_x, $this->new_y, 0);
364
365
        return true;
366
    }
367
368
    /**
369
     * Resize Action
370
     *
371
     * For GD 2.01+ the new copyresampled function is used
372
     * It uses a bicubic interpolation algorithm to get far
373
     * better result.
374
     *
375
     * @param int   $new_x   New width
376
     * @param int   $new_y   New height
377
     * @param array $options Optional parameters
378
     *                       <ul>
379
     *                       <li>'scaleMethod': "pixel" or "smooth"</li>
380
     *                       </ul>
381
     *
382
     * @return bool|PEAR_Error TRUE on success or PEAR_Error object on error
383
     * @access protected
384
     */
385
    public function _resize($new_x=null, $new_y=null, $options = null)
386
    {
387
        if (true === $this->resized) {
388
            return PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);
389
        }
390
391
        if ($this->new_x == $new_x && $this->new_y == $new_y) {
392
            return true;
393
        }
394
395
        $scaleMethod = $this->_getOption('scaleMethod', $options, 'smooth');
396
397
        // Make sure to get a true color image if doing resampled resizing
398
        // otherwise get the same type of image
399
        $trueColor = ('pixel' == $scaleMethod) ? null : true;
400
        $new_img   = $this->_createImage($new_x, $new_y, $trueColor);
401
402
        $icr_res = null;
403
        if ('pixel' != $scaleMethod && function_exists('ImageCopyResampled')) {
404
            $icr_res = ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
405
        }
406
        if (!$icr_res) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $icr_res of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
407
            ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
408
        }
409
        $this->oldImage    = $this->imageHandle;
410
        $this->imageHandle = $new_img;
411
        $this->resized     = true;
412
413
        $this->new_x = $new_x;
414
        $this->new_y = $new_y;
415
416
        return true;
417
    }
418
419
    /**
420
     * Adjusts the image gamma
421
     *
422
     * @param float $outputgamma
423
     *
424
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
425
     * @access public
426
     */
427
    public function gamma($outputgamma = 1.0)
428
    {
429
        if (1.0 != $outputgamma) {
430
            ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
431
        }
432
433
        return true;
434
    }
435
436
    /**
437
     * Helper method to save to a file or output the image
438
     *
439
     * @param string $filename  the name of the file to write to (blank to output)
440
     * @param string $types     define the output format, default
441
     *                          is the current used format
442
     * @param int    $quality   output DPI, default is 75
443
     *
444
     * @return bool|PEAR_Error TRUE on success or PEAR_Error object on error
445
     * @access protected
446
     */
447
    public function _generate($filename, $type = '', $quality = null)
448
    {
449
        $type    = strtolower(('' == $type) ? $this->type : $type);
450
        $options = (is_array($quality)) ? $quality : array();
0 ignored issues
show
introduced by
The condition is_array($quality) is always false.
Loading history...
451
        switch ($type) {
452
            case 'jpg':
453
                $type = 'jpeg';
454
                // no break
455
            case 'jpeg':
456
                if (is_numeric($quality)) {
457
                    $options['quality'] = $quality;
458
                }
459
                $quality = $this->_getOption('quality', $options, 75);
460
                break;
461
        }
462
        if (!$this->supportsType($type, 'w')) {
463
            return PEAR::raiseError('Image type not supported for output', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
464
        }
465
466
        if ('' == $filename) {
467
            header('Content-type: ' . $this->getMimeType($type));
468
            $action = 'output image';
469
        } else {
470
            $action = 'save image to file';
471
        }
472
473
        $functionName = 'image' . $type;
474
        switch ($type) {
475
            case 'jpeg':
476
                $result = $functionName($this->imageHandle, $filename, $quality);
477
                break;
478
            default:
479
                if ('' == $filename) {
480
                    $result = $functionName($this->imageHandle);
481
                } else {
482
                    $result = $functionName($this->imageHandle, $filename);
483
                }
484
        }
485
        if (!$result) {
486
            return PEAR::raiseError('Couldn\'t ' . $action, IMAGE_TRANSFORM_ERROR_IO);
487
        }
488
        $this->imageHandle = $this->oldImage;
489
        if (!$this->keep_settings_on_save) {
490
            $this->free();
491
        }
492
493
        return true;
494
    } // End save
495
496
    /**
497
     * Displays image without saving and lose changes.
498
     *
499
     * This method adds the Content-type HTTP header
500
     *
501
     * @param string $type    (JPEG, PNG...);
502
     * @param int    $quality 75
503
     *
504
     * @return bool|PEAR_Error TRUE or PEAR_Error object on error
505
     * @access public
506
     */
507
    public function display($type = '', $quality = null)
508
    {
509
        return $this->_generate('', $type, $quality);
510
    }
511
512
    /**
513
     * Saves the image to a file
514
     *
515
     * @param string $filename  the name of the file to write to
516
     * @param string $type      the output format, default
517
     *                          is the current used format
518
     * @param int    $quality   default is 75
519
     *
520
     * @return bool|PEAR_Error TRUE on success or PEAR_Error object on error
521
     * @access public
522
     */
523
    public function save($filename, $type = '', $quality = null)
524
    {
525
        if (!trim($filename)) {
526
            return PEAR::raiseError('Filename missing', IMAGE_TRANSFORM_ERROR_ARGUMENT);
527
        }
528
529
        return $this->_generate($filename, $type, $quality);
530
    }
531
532
    /**
533
     * Destroys image handle
534
     *
535
     * @access public
536
     */
537
    public function free()
538
    {
539
        $this->resized = false;
540
        if (is_resource($this->imageHandle)) {
541
            ImageDestroy($this->imageHandle);
542
        }
543
        $this->imageHandle = null;
544
        if (is_resource($this->oldImage)) {
545
            ImageDestroy($this->oldImage);
546
        }
547
        $this->oldImage = null;
548
    }
549
550
    /**
551
     * Returns a new image for temporary processing
552
     *
553
     * @param int  $width     width of the new image
554
     * @param int  $height    height of the new image
555
     * @param bool $trueColor force which type of image to create
556
     * @return resource a GD image resource
557
     * @access protected
558
     */
559
    public function _createImage($width = -1, $height = -1, $trueColor = null)
560
    {
561
        if ($width == -1) {
562
            $width = $this->new_x;
563
        }
564
        if ($height == -1) {
565
            $height = $this->new_y;
566
        }
567
568
        $new_img = null;
569
        if (is_null($trueColor)) {
570
            if (function_exists('imageistruecolor')) {
571
                $createtruecolor = imageistruecolor($this->imageHandle);
572
            } else {
573
                $createtruecolor = true;
574
            }
575
        } else {
576
            $createtruecolor = $trueColor;
577
        }
578
        if ($createtruecolor
579
            && function_exists('ImageCreateTrueColor')) {
580
            $new_img = @ImageCreateTrueColor($width, $height);
581
            //GIF Transparent Patch
582
            if ('gif' != $this->type) {
583
                imagealphablending($new_img, false);
584
                imagesavealpha($new_img, true);
585
            }
586
            //End GIF Transparent Patch
587
        }
588
        if (!$new_img) {
589
            $new_img = ImageCreate($width, $height);
590
            imagepalettecopy($new_img, $this->imageHandle);
591
            $color = imagecolortransparent($this->imageHandle);
592
            if ($color != -1) {
593
                imagecolortransparent($new_img, $color);
594
                imagefill($new_img, 0, 0, $color);
595
            }
596
        }
597
598
        //GIF Transparent Patch
599
        if ('gif' == $this->type) {
600
            $transparencyIndex = imagecolortransparent($this->imageHandle);
601
            $transparencyColor = array('red' => 255, 'green' => 255, 'blue' => 255);
602
603
            if ($transparencyIndex >= 0) {
604
                $transparencyColor = imagecolorsforindex($this->imageHandle, $transparencyIndex);
605
            }
606
607
            $transparencyIndex = imagecolorallocate($new_img, $transparencyColor['red'], $transparencyColor['green'], $transparencyColor['blue']);
608
            imagefill($new_img, 0, 0, $transparencyIndex);
609
            imagecolortransparent($new_img, $transparencyIndex);
610
        }
611
612
        //End GIF Transparent Patch
613
614
        return $new_img;
615
    }
616
}
617