1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* Cairo implementation for Image_Transform package |
6
|
|
|
* |
7
|
|
|
* PHP versions 4 and 5 |
8
|
|
|
* |
9
|
|
|
* @category Image |
10
|
|
|
* @package Image_Transform |
11
|
|
|
* @subpackage Image_Transform_Driver_Cairowrapper |
12
|
|
|
* @author Christian Weiske <[email protected]> |
13
|
|
|
* @copyright 2008 The PHP Group |
14
|
|
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL |
15
|
|
|
* @version CVS: $Id: Cairowrapper.php 288112 2009-09-06 21:02:37Z cweiske $ |
16
|
|
|
* @link http://pear.php.net/package/Image_Transform |
17
|
|
|
*/ |
18
|
|
|
require_once 'Image/Transform.php'; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Cairo implementation for Image_Transform package using pecl's cairo_wrapper |
22
|
|
|
* extension. |
23
|
|
|
* |
24
|
|
|
* Supports png files only. |
25
|
|
|
* |
26
|
|
|
* @category Image |
27
|
|
|
* @package Image_Transform |
28
|
|
|
* @subpackage Image_Transform_Driver_Cairowrapper |
29
|
|
|
* @author Christian Weiske <[email protected]> |
30
|
|
|
* @copyright 2008 The PHP Group |
31
|
|
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL |
32
|
|
|
* @version Release: @package_version@ |
33
|
|
|
* @link http://pear.php.net/package/Image_Transform |
34
|
|
|
*/ |
35
|
|
|
class Image_Transform_Driver_Cairowrapper extends Image_Transform |
|
|
|
|
36
|
|
|
{ |
37
|
|
|
var $surface = null; |
|
|
|
|
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Supported image types |
41
|
|
|
* |
42
|
|
|
* @var array |
43
|
|
|
* @access protected |
44
|
|
|
*/ |
45
|
|
|
var $_supported_image_types = array( |
|
|
|
|
46
|
|
|
'png' => 'rw' |
47
|
|
|
); |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Check settings |
51
|
|
|
*/ |
52
|
|
|
function Image_Transform_Driver_Cairowrapper() |
|
|
|
|
53
|
|
|
{ |
54
|
|
|
$this->__construct(); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
|
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Create object and check if cairo_wrapper is loaded |
61
|
|
|
*/ |
62
|
|
|
function __construct() |
|
|
|
|
63
|
|
|
{ |
64
|
|
|
if (!PEAR::loadExtension('cairo_wrapper')) { |
65
|
|
|
$this->isError( |
66
|
|
|
PEAR::raiseError( |
|
|
|
|
67
|
|
|
'cairo_wrapper extension is not available.', |
68
|
|
|
IMAGE_TRANSFORM_ERROR_UNSUPPORTED |
69
|
|
|
) |
70
|
|
|
); |
71
|
|
|
} |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
|
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Loads an image from file |
78
|
|
|
* |
79
|
|
|
* @param string $image filename |
80
|
|
|
* |
81
|
|
|
* @return bool|PEAR_Error TRUE or a PEAR_Error object on error |
82
|
|
|
* |
83
|
|
|
* @access public |
84
|
|
|
*/ |
85
|
|
|
function load($image) |
|
|
|
|
86
|
|
|
{ |
87
|
|
|
$this->free(); |
88
|
|
|
|
89
|
|
|
$this->image = $image; |
90
|
|
|
$result = $this->_get_image_details($image); |
91
|
|
|
if (PEAR::isError($result)) { |
92
|
|
|
return $result; |
93
|
|
|
} |
94
|
|
|
if (!$this->supportsType($this->type, 'r')) { |
95
|
|
|
return PEAR::raiseError('Image type not supported for input', |
|
|
|
|
96
|
|
|
IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
$this->surface = cairo_image_surface_create_from_png($this->image); |
100
|
|
|
if (cairo_surface_status($this->surface) != CAIRO_STATUS_SUCCESS) { |
101
|
|
|
$this->surface = null; |
102
|
|
|
return PEAR::raiseError('Error while loading image file.', |
|
|
|
|
103
|
|
|
IMAGE_TRANSFORM_ERROR_IO); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
return true; |
|
|
|
|
107
|
|
|
}//function load(..) |
|
|
|
|
108
|
|
|
|
109
|
|
|
|
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Resize the image |
113
|
|
|
* |
114
|
|
|
* @param int $new_x New width |
115
|
|
|
* @param int $new_y New height |
116
|
|
|
* @param array $options Optional parameters |
|
|
|
|
117
|
|
|
* |
118
|
|
|
* @return bool|PEAR_Error TRUE on success or PEAR_Error object on error |
119
|
|
|
* |
120
|
|
|
* @access protected |
121
|
|
|
*/ |
122
|
|
|
function _resize($new_x, $new_y, $options = null) |
|
|
|
|
123
|
|
|
{ |
124
|
|
View Code Duplication |
if ($this->resized === true) { |
|
|
|
|
125
|
|
|
return PEAR::raiseError( |
|
|
|
|
126
|
|
|
'You have already resized the image without saving it.' |
127
|
|
|
. ' Your previous resizing will be overwritten', |
128
|
|
|
null, PEAR_ERROR_TRIGGER, E_USER_NOTICE |
129
|
|
|
); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
if ($this->new_x == $new_x && $this->new_y == $new_y) { |
133
|
|
|
return true; |
|
|
|
|
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
$xFactor = $new_x / $this->img_x; |
137
|
|
|
$yFactor = $new_y / $this->img_y; |
138
|
|
|
|
139
|
|
|
$outputSurface = cairo_image_surface_create( |
140
|
|
|
CAIRO_FORMAT_ARGB32, $new_x, $new_y |
141
|
|
|
); |
142
|
|
|
$outputContext = cairo_create($outputSurface); |
143
|
|
|
|
144
|
|
|
cairo_scale($outputContext, $xFactor, $yFactor); |
145
|
|
|
|
146
|
|
|
cairo_set_source_surface($outputContext, $this->surface, 0, 0); |
147
|
|
|
cairo_paint($outputContext); |
148
|
|
|
|
149
|
|
|
cairo_destroy($outputContext); |
150
|
|
|
|
151
|
|
|
cairo_surface_destroy($this->surface); |
152
|
|
|
|
153
|
|
|
$this->surface = $outputSurface; |
154
|
|
|
|
155
|
|
|
$this->new_x = $new_x; |
156
|
|
|
$this->new_y = $new_y; |
157
|
|
|
return true; |
|
|
|
|
158
|
|
|
}//function _resize(..) |
|
|
|
|
159
|
|
|
|
160
|
|
|
|
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Saves the scaled image into a file. |
164
|
|
|
* |
165
|
|
|
* @param string $filename The filename to save to |
166
|
|
|
* @param mixed $type ignored |
167
|
|
|
* @param mixed $quality ignored |
168
|
|
|
* |
169
|
|
|
* @return bool|PEAR_Error TRUE on success or PEAR_Error object on error |
170
|
|
|
* |
171
|
|
|
* @access public |
172
|
|
|
*/ |
173
|
|
|
function save($filename, $type = null, $quality = null) |
|
|
|
|
174
|
|
|
{ |
175
|
|
|
cairo_surface_write_to_png($this->surface, $filename); |
176
|
|
|
$this->free(); |
177
|
|
|
return true; |
|
|
|
|
178
|
|
|
}//function save(..) |
|
|
|
|
179
|
|
|
|
180
|
|
|
|
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* Returns the surface of the image so it can be modified further |
184
|
|
|
* |
185
|
|
|
* @return resource |
|
|
|
|
186
|
|
|
* |
187
|
|
|
* @access public |
188
|
|
|
*/ |
189
|
|
|
function getHandle() |
|
|
|
|
190
|
|
|
{ |
191
|
|
|
return $this->surface; |
192
|
|
|
}//function getHandle() |
193
|
|
|
|
194
|
|
|
|
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Frees cairo handles |
198
|
|
|
* |
199
|
|
|
* @return void |
200
|
|
|
* |
201
|
|
|
* @access public |
202
|
|
|
*/ |
203
|
|
|
function free() |
|
|
|
|
204
|
|
|
{ |
205
|
|
|
$this->resized = false; |
206
|
|
|
if (is_resource($this->surface)) { |
207
|
|
|
cairo_surface_destroy($this->surface); |
208
|
|
|
} |
209
|
|
|
$this->surface = null; |
210
|
|
|
}//function free() |
211
|
|
|
|
212
|
|
|
|
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* Mirrors the image vertically |
216
|
|
|
* Uses an affine transformation matrix to flip the image. |
217
|
|
|
* |
218
|
|
|
* @return void |
219
|
|
|
*/ |
220
|
|
View Code Duplication |
function flip() |
|
|
|
|
221
|
|
|
{ |
222
|
|
|
$outputSurface = cairo_image_surface_create( |
223
|
|
|
CAIRO_FORMAT_ARGB32, $this->img_x, $this->img_y |
224
|
|
|
); |
225
|
|
|
$outputContext = cairo_create($outputSurface); |
226
|
|
|
// xx, yx, xy, yy, x0, y0 |
227
|
|
|
$matrix = cairo_matrix_create(1, 0, 0, -1, 0, $this->img_y); |
228
|
|
|
|
229
|
|
|
cairo_set_matrix($outputContext, $matrix); |
230
|
|
|
cairo_set_source_surface($outputContext, $this->surface, 0, 0); |
231
|
|
|
cairo_paint($outputContext); |
232
|
|
|
|
233
|
|
|
cairo_destroy($outputContext); |
234
|
|
|
cairo_surface_destroy($this->surface); |
235
|
|
|
|
236
|
|
|
$this->surface = $outputSurface; |
237
|
|
|
}//function flip() |
238
|
|
|
|
239
|
|
|
|
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Mirrors the image horizontally. |
243
|
|
|
* Uses an affine transformation matrix to mirror the image. |
244
|
|
|
* |
245
|
|
|
* 123 -> 321 |
246
|
|
|
* |
247
|
|
|
* @return void |
248
|
|
|
*/ |
249
|
|
View Code Duplication |
function mirror() |
|
|
|
|
250
|
|
|
{ |
251
|
|
|
$outputSurface = cairo_image_surface_create( |
252
|
|
|
CAIRO_FORMAT_ARGB32, $this->img_x, $this->img_y |
253
|
|
|
); |
254
|
|
|
$outputContext = cairo_create($outputSurface); |
255
|
|
|
// xx, yx, xy, yy, x0, y0 |
256
|
|
|
$matrix = cairo_matrix_create(-1, 0, 0, 1, $this->img_x, 0); |
257
|
|
|
|
258
|
|
|
cairo_set_matrix($outputContext, $matrix); |
259
|
|
|
cairo_set_source_surface($outputContext, $this->surface, 0, 0); |
260
|
|
|
cairo_paint($outputContext); |
261
|
|
|
|
262
|
|
|
cairo_destroy($outputContext); |
263
|
|
|
cairo_surface_destroy($this->surface); |
264
|
|
|
|
265
|
|
|
$this->surface = $outputSurface; |
266
|
|
|
}//function mirror() |
267
|
|
|
|
268
|
|
|
}//class Image_Transform_Driver_Cairowrapper extends Image_Transform |
269
|
|
|
?> |
|
|
|
|
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.