Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/* vim: set expandtab tabstop=4 shiftwidth=4: */
4
 
5
/**
6
 * imagick PECL extension 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 license@php.net so we can mail you a copy immediately.
15
 *
16
 * @category   Image
17
 * @package    Image_Transform
18
 * @subpackage Image_Transform_Driver_Imagick2
19
 * @author     Alan Knowles <alan@akbkhome.com>
20
 * @author     Peter Bowyer <peter@mapledesign.co.uk>
21
 * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
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: Imagick2.php,v 1.10 2007/04/19 16:36:09 dufuz Exp $
25
 * @link       http://pear.php.net/package/Image_Transform
26
 */
27
 
28
require_once 'Image/Transform.php';
29
 
30
/**
31
 * imagick PECL extension implementation for Image_Transform package
32
 *
33
 * EXPERIMENTAL - please report bugs
34
 * Use the latest cvs version of imagick PECL
35
 *
36
 * @category   Image
37
 * @package    Image_Transform
38
 * @subpackage Image_Transform_Driver_Imagick2
39
 * @author     Alan Knowles <alan@akbkhome.com>
40
 * @author     Peter Bowyer <peter@mapledesign.co.uk>
41
 * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
42
 * @copyright  2002-2005 The PHP Group
43
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
44
 * @version    Release: @package_version@
45
 * @link       http://pear.php.net/package/Image_Transform
46
 * @since      PHP 4.0
47
 */
48
class Image_Transform_Driver_Imagick2 extends Image_Transform
49
{
50
    /**
51
     * Handler of the imagick image ressource
52
     * @var array
53
     */
54
    var $imageHandle = null;
55
 
56
    /**
57
     * @see __construct()
58
     */
59
    function Image_Transform_Driver_Imagick2()
60
    {
61
        $this->__construct();
62
    } // End Image_Transform_Driver_Imagick2
63
 
64
    /**
65
     * @see http://www.imagemagick.org/www/formats.html
66
     */
67
    function __construct()
68
    {
69
        if (PEAR::loadExtension('imagick')) {
70
            include 'Image/Transform/Driver/Imagick/ImageTypes.php';
71
        } else {
72
            $this->isError(PEAR::raiseError('Couldn\'t find the imagick extension.',
73
                IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
74
        }
75
    }
76
 
77
    /**
78
     * Loads an image
79
     *
80
     * @param string $image filename
81
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
82
     * @access public
83
     */
84
    function load($image)
85
    {
86
        if (!($this->imageHandle = imagick_readimage($image))) {
87
            $this->free();
88
            return $this->raiseError('Couldn\'t load image.',
89
                IMAGE_TRANSFORM_ERROR_IO);
90
        }
91
        if (imagick_iserror($this->imageHandle)) {
92
            return $this->raiseError('Couldn\'t load image.',
93
                IMAGE_TRANSFORM_ERROR_IO);
94
        }
95
 
96
        $this->image = $image;
97
        $result = $this->_get_image_details($image);
98
        if (PEAR::isError($result)) {
99
            return $result;
100
        }
101
 
102
        return true;
103
    } // End load
104
 
105
    /**
106
     * Resize Action
107
     *
108
     * @param int   $new_x   New width
109
     * @param int   $new_y   New height
110
     * @param mixed $options Optional parameters
111
     *
112
     * @return bool|PEAR_Error TRUE or PEAR_Error object on error
113
     * @access protected
114
     */
115
    function _resize($new_x, $new_y, $options = null)
116
    {
117
        if (!imagick_resize($this->imageHandle, $new_x, $new_y, IMAGICK_FILTER_UNKNOWN , 1)) {
118
            return $this->raiseError('Couldn\'t resize image.',
119
                IMAGE_TRANSFORM_ERROR_FAILED);
120
        }
121
 
122
        $this->new_x = $new_x;
123
        $this->new_y = $new_y;
124
        return true;
125
 
126
    } // End resize
127
 
128
    /**
129
     * Rotates the current image
130
     * Note: color mask are currently not supported
131
     *
132
     * @param   int     Rotation angle in degree
133
     * @param   array   No options are currently supported
134
     *
135
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
136
     * @access public
137
     */
138
    function rotate($angle, $options = null)
139
    {
140
        if (($angle % 360) == 0) {
141
            return true;
142
        }
143
        if (!imagick_rotate($this->imageHandle, $angle)) {
144
            return $this->raiseError('Cannot create a new imagick image for the rotation.',
145
                IMAGE_TRANSFORM_ERROR_FAILED);
146
        }
147
 
148
        $this->new_x = imagick_getwidth($this->imageHandle);
149
        $this->new_y = imagick_getheight($this->imageHandle);
150
        return true;
151
 
152
    } // End rotate
153
 
154
    /**
155
     * addText
156
     *
157
     * @param   array   options     Array contains options
158
     *                              array(
159
     *                                  'text'  The string to draw
160
     *                                  'x'     Horizontal position
161
     *                                  'y'     Vertical Position
162
     *                                  'Color' Font color
163
     *                                  'font'  Font to be used
164
     *                                  'size'  Size of the fonts in pixel
165
     *                                  'resize_first'  Tell if the image has to be resized
166
     *                                                  before drawing the text
167
     *                              )
168
     *
169
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
170
     * @access public
171
     */
172
    function addText($params)
173
    {
174
        static $default_params = array(
175
                                'text'          => 'This is a Text',
176
                                'x'             => 10,
177
                                'y'             => 20,
178
                                'size'          => 12,
179
                                'color'         => 'red',
180
                                'font'          => 'Helvetica',
181
                                'resize_first'  => false // Carry out the scaling of the image before annotation?
182
                                );
183
        $params = array_merge($default_params, $params);
184
 
185
 
186
        $params['color']= is_array($params['color'])?$this->colorarray2colorhex($params['color']):strtolower($params['color']);
187
 
188
 
189
        static $cmds = array(
190
            'setfillcolor' => 'color',
191
            'setfontsize'  => 'size',
192
            'setfontface'  => 'font'
193
        );
194
        imagick_begindraw($this->imageHandle ) ;
195
 
196
        foreach ($cmds as $cmd => $v) {
197
            if (!call_user_func('imagick_' . $cmd, $this->imageHandle, $parms[$v])) {
198
                return $this->raiseError("Problem with adding Text::{$v} = {$parms[$v]}",
199
                    IMAGE_TRANSFORM_ERROR_FAILED);
200
            }
201
        }
202
        if (!imagick_drawannotation($this->imageHandle, $params['x'], $params['y'], $params['text'])) {
203
            return $this->raiseError('Problem with adding Text',
204
                IMAGE_TRANSFORM_ERROR_FAILED);
205
        }
206
 
207
        return true;
208
 
209
    } // End addText
210
 
211
 
212
    /**
213
     * Saves the image to a file
214
     *
215
     * @param $filename string the name of the file to write to
216
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
217
     * @access public
218
     */
219
    function save($filename, $type = '', $quality = null)
220
    {
221
        $options = (is_array($quality)) ? $quality : array();
222
        if (is_numeric($quality)) {
223
            $options['quality'] = $quality;
224
        }
225
        $quality = $this->_getOption('quality', $options, 75);
226
        imagick_setcompressionquality($this->imageHandle, $quality);
227
 
228
        if ($type && strcasecmp($type, $this->type)
229
            && !imagick_convert($this->imageHandle, $type)) {
230
            return $this->raiseError('Couldn\'t save image to file (conversion failed).',
231
                IMAGE_TRANSFORM_ERROR_FAILED);
232
        }
233
 
234
        if (!imagick_write($this->imageHandle, $filename)) {
235
            return $this->raiseError('Couldn\'t save image to file.',
236
                IMAGE_TRANSFORM_ERROR_IO);
237
        }
238
        $this->free();
239
        return true;
240
 
241
    } // End save
242
 
243
    /**
244
     * Displays image without saving and lose changes
245
     *
246
     * This method adds the Content-type HTTP header
247
     *
248
     * @param string type (JPG,PNG...);
249
     * @param int quality 75
250
     *
251
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
252
     * @access public
253
     */
254
    function display($type = '', $quality = null)
255
    {
256
        $options = (is_array($quality)) ? $quality : array();
257
        if (is_numeric($quality)) {
258
            $options['quality'] = $quality;
259
        }
260
        $quality = $this->_getOption('quality', $options, 75);
261
        imagick_setcompressionquality($this->imageHandle, $quality);
262
 
263
        if ($type && strcasecomp($type, $this->type)
264
            && !imagick_convert($this->imageHandle, $type)) {
265
            return $this->raiseError('Couldn\'t save image to file (conversion failed).',
266
                IMAGE_TRANSFORM_ERROR_FAILED);
267
        }
268
        if (!($image = imagick_image2blob($this->imageHandle))) {
269
            return $this->raiseError('Couldn\'t display image.',
270
                IMAGE_TRANSFORM_ERROR_IO);
271
        }
272
        header('Content-type: ' . imagick_getmimetype($this->imageHandle));
273
        echo $image;
274
        $this->free();
275
        return true;
276
    }
277
 
278
    /**
279
     * Adjusts the image gamma
280
     *
281
     * @param float $outputgamma
282
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
283
     * @access public
284
     */
285
    function gamma($outputgamma = 1.0) {
286
        if ($outputgamma != 1.0) {
287
            imagick_gamma($this->imageHandle, $outputgamma);
288
        }
289
        return true;
290
    }
291
 
292
    /**
293
     * Crops the image
294
     *
295
     * @param int width Cropped image width
296
     * @param int height Cropped image height
297
     * @param int x X-coordinate to crop at
298
     * @param int y Y-coordinate to crop at
299
     *
300
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
301
     * @access public
302
     */
303
    function crop($width, $height, $x = 0, $y = 0)
304
    {
305
        // Sanity check
306
        if (!$this->intersects($width, $height, $x, $y)) {
307
            return PEAR::raiseError('Nothing to crop', IMAGE_TRANSFORM_ERROR_OUTOFBOUND);
308
        }
309
        if (!imagick_crop($this->imageHandle, $x, $y, $width, $height)) {
310
            return $this->raiseError('Couldn\'t crop image.',
311
                IMAGE_TRANSFORM_ERROR_FAILED);
312
        }
313
 
314
        // I think that setting img_x/y is wrong, but scaleByLength() & friends
315
        // mess up the aspect after a crop otherwise.
316
        $this->new_x = $width;
317
        $this->new_y = $height;
318
 
319
        return true;
320
    }
321
 
322
    /**
323
     * Horizontal mirroring
324
     *
325
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
326
     * @access public
327
     */
328
    function mirror()
329
    {
330
        if (!imagick_flop($this->imageHandle)) {
331
            return $this->raiseError('Couldn\'t mirror the image.',
332
                IMAGE_TRANSFORM_ERROR_FAILED);
333
        }
334
        return true;
335
    }
336
 
337
    /**
338
     * Vertical mirroring
339
     *
340
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
341
     * @access public
342
     */
343
    function flip()
344
    {
345
        if (!imagick_flip($this->imageHandle)) {
346
            return $this->raiseError('Couldn\'t flip the image.',
347
                IMAGE_TRANSFORM_ERROR_FAILED);
348
        }
349
        return true;
350
    }
351
 
352
    /**
353
     * Destroy image handle
354
     *
355
     * @access public
356
     */
357
    function free()
358
    {
359
        if (is_resource($this->imageHandle)) {
360
            imagick_destroyhandle($this->imageHandle);
361
        }
362
        $this->imageHandle = null;
363
    }
364
 
365
    /**
366
     * RaiseError Method - shows imagick Raw errors.
367
     *
368
     * @param string $message message = prefixed message..
369
     * @param int    $code error code
370
     * @return PEAR error object
371
     * @access protected
372
     */
373
    function raiseError($message, $code = 0)
374
    {
375
        if (is_resource($this->imageHandle)) {
376
            $message .= "\nReason: "
377
                        .  imagick_failedreason($this->imageHandle)
378
                        . "\nDescription: "
379
                        . imagick_faileddescription($this->imageHandle);
380
        }
381
        return PEAR::raiseError($message, $code);
382
    }
383
 
384
} // End class Image_Transform_Driver_Imagick2