|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Barcode |
|
17 * @subpackage Renderer |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Image.php 22999 2010-09-23 19:43:14Z mikaelkael $ |
|
21 */ |
|
22 |
|
23 /** @see Zend_Barcode_Renderer_RendererAbstract*/ |
|
24 require_once 'Zend/Barcode/Renderer/RendererAbstract.php'; |
|
25 |
|
26 /** |
|
27 * Class for rendering the barcode as image |
|
28 * |
|
29 * @category Zend |
|
30 * @package Zend_Barcode |
|
31 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
32 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
33 */ |
|
34 class Zend_Barcode_Renderer_Image extends Zend_Barcode_Renderer_RendererAbstract |
|
35 { |
|
36 /** |
|
37 * List of authorized output format |
|
38 * @var array |
|
39 */ |
|
40 protected $_allowedImageType = array( |
|
41 'png', |
|
42 'jpeg', |
|
43 'gif', |
|
44 ); |
|
45 |
|
46 /** |
|
47 * Image format |
|
48 * @var string |
|
49 */ |
|
50 protected $_imageType = 'png'; |
|
51 |
|
52 /** |
|
53 * Resource for the image |
|
54 * @var resource |
|
55 */ |
|
56 protected $_resource = null; |
|
57 |
|
58 /** |
|
59 * Resource for the font and bars color of the image |
|
60 * @var integer |
|
61 */ |
|
62 protected $_imageForeColor = null; |
|
63 |
|
64 /** |
|
65 * Resource for the background color of the image |
|
66 * @var integer |
|
67 */ |
|
68 protected $_imageBackgroundColor = null; |
|
69 |
|
70 /** |
|
71 * Height of the rendered image wanted by user |
|
72 * @var integer |
|
73 */ |
|
74 protected $_userHeight = 0; |
|
75 |
|
76 /** |
|
77 * Width of the rendered image wanted by user |
|
78 * @var integer |
|
79 */ |
|
80 protected $_userWidth = 0; |
|
81 |
|
82 public function __construct($options = null) |
|
83 { |
|
84 if (!function_exists('gd_info')) { |
|
85 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
86 throw new Zend_Barcode_Renderer_Exception('Zend_Barcode_Renderer_Image requires the GD extension'); |
|
87 } |
|
88 |
|
89 parent::__construct($options); |
|
90 } |
|
91 |
|
92 /** |
|
93 * Set height of the result image |
|
94 * @param null|integer $value |
|
95 * @return Zend_Image_Barcode_Abstract |
|
96 * @throw Zend_Image_Barcode_Exception |
|
97 */ |
|
98 public function setHeight($value) |
|
99 { |
|
100 if (!is_numeric($value) || intval($value) < 0) { |
|
101 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
102 throw new Zend_Barcode_Renderer_Exception( |
|
103 'Image height must be greater than or equals 0' |
|
104 ); |
|
105 } |
|
106 $this->_userHeight = intval($value); |
|
107 return $this; |
|
108 } |
|
109 |
|
110 /** |
|
111 * Get barcode height |
|
112 * |
|
113 * @return int |
|
114 */ |
|
115 public function getHeight() |
|
116 { |
|
117 return $this->_userHeight; |
|
118 } |
|
119 |
|
120 /** |
|
121 * Set barcode width |
|
122 * |
|
123 * @param mixed $value |
|
124 * @return void |
|
125 */ |
|
126 public function setWidth($value) |
|
127 { |
|
128 if (!is_numeric($value) || intval($value) < 0) { |
|
129 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
130 throw new Zend_Barcode_Renderer_Exception( |
|
131 'Image width must be greater than or equals 0' |
|
132 ); |
|
133 } |
|
134 $this->_userWidth = intval($value); |
|
135 return $this; |
|
136 } |
|
137 |
|
138 /** |
|
139 * Get barcode width |
|
140 * |
|
141 * @return int |
|
142 */ |
|
143 public function getWidth() |
|
144 { |
|
145 return $this->_userWidth; |
|
146 } |
|
147 |
|
148 /** |
|
149 * Set an image resource to draw the barcode inside |
|
150 * |
|
151 * @param resource $value |
|
152 * @return Zend_Barcode_Renderer |
|
153 * @throw Zend_Barcode_Renderer_Exception |
|
154 */ |
|
155 public function setResource($image) |
|
156 { |
|
157 if (gettype($image) != 'resource' || get_resource_type($image) != 'gd') { |
|
158 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
159 throw new Zend_Barcode_Renderer_Exception( |
|
160 'Invalid image resource provided to setResource()' |
|
161 ); |
|
162 } |
|
163 $this->_resource = $image; |
|
164 return $this; |
|
165 } |
|
166 |
|
167 /** |
|
168 * Set the image type to produce (png, jpeg, gif) |
|
169 * |
|
170 * @param string $value |
|
171 * @return Zend_Barcode_RendererAbstract |
|
172 * @throw Zend_Barcode_Renderer_Exception |
|
173 */ |
|
174 public function setImageType($value) |
|
175 { |
|
176 if ($value == 'jpg') { |
|
177 $value = 'jpeg'; |
|
178 } |
|
179 |
|
180 if (!in_array($value, $this->_allowedImageType)) { |
|
181 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
182 throw new Zend_Barcode_Renderer_Exception(sprintf( |
|
183 'Invalid type "%s" provided to setImageType()', |
|
184 $value |
|
185 )); |
|
186 } |
|
187 |
|
188 $this->_imageType = $value; |
|
189 return $this; |
|
190 } |
|
191 |
|
192 /** |
|
193 * Retrieve the image type to produce |
|
194 * |
|
195 * @return string |
|
196 */ |
|
197 public function getImageType() |
|
198 { |
|
199 return $this->_imageType; |
|
200 } |
|
201 |
|
202 /** |
|
203 * Initialize the image resource |
|
204 * |
|
205 * @return void |
|
206 */ |
|
207 protected function _initRenderer() |
|
208 { |
|
209 if (!extension_loaded('gd')) { |
|
210 require_once 'Zend/Barcode/Exception.php'; |
|
211 $e = new Zend_Barcode_Exception( |
|
212 'Gd extension must be loaded to render barcode as image' |
|
213 ); |
|
214 $e->setIsRenderable(false); |
|
215 throw $e; |
|
216 } |
|
217 |
|
218 $barcodeWidth = $this->_barcode->getWidth(true); |
|
219 $barcodeHeight = $this->_barcode->getHeight(true); |
|
220 |
|
221 if ($this->_resource !== null) { |
|
222 $foreColor = $this->_barcode->getForeColor(); |
|
223 $backgroundColor = $this->_barcode->getBackgroundColor(); |
|
224 $this->_imageBackgroundColor = imagecolorallocate( |
|
225 $this->_resource, |
|
226 ($backgroundColor & 0xFF0000) >> 16, |
|
227 ($backgroundColor & 0x00FF00) >> 8, |
|
228 $backgroundColor & 0x0000FF |
|
229 ); |
|
230 $this->_imageForeColor = imagecolorallocate( |
|
231 $this->_resource, |
|
232 ($foreColor & 0xFF0000) >> 16, |
|
233 ($foreColor & 0x00FF00) >> 8, |
|
234 $foreColor & 0x0000FF |
|
235 ); |
|
236 } else { |
|
237 $width = $barcodeWidth; |
|
238 $height = $barcodeHeight; |
|
239 if ($this->_userWidth && $this->_barcode->getType() != 'error') { |
|
240 $width = $this->_userWidth; |
|
241 } |
|
242 if ($this->_userHeight && $this->_barcode->getType() != 'error') { |
|
243 $height = $this->_userHeight; |
|
244 } |
|
245 |
|
246 $foreColor = $this->_barcode->getForeColor(); |
|
247 $backgroundColor = $this->_barcode->getBackgroundColor(); |
|
248 $this->_resource = imagecreatetruecolor($width, $height); |
|
249 |
|
250 $this->_imageBackgroundColor = imagecolorallocate( |
|
251 $this->_resource, |
|
252 ($backgroundColor & 0xFF0000) >> 16, |
|
253 ($backgroundColor & 0x00FF00) >> 8, |
|
254 $backgroundColor & 0x0000FF |
|
255 ); |
|
256 $this->_imageForeColor = imagecolorallocate( |
|
257 $this->_resource, |
|
258 ($foreColor & 0xFF0000) >> 16, |
|
259 ($foreColor & 0x00FF00) >> 8, |
|
260 $foreColor & 0x0000FF |
|
261 ); |
|
262 $white = imagecolorallocate($this->_resource, 255, 255, 255); |
|
263 imagefilledrectangle($this->_resource, 0, 0, $width - 1, $height - 1, $white); |
|
264 } |
|
265 $this->_adjustPosition(imagesy($this->_resource), imagesx($this->_resource)); |
|
266 imagefilledrectangle( |
|
267 $this->_resource, |
|
268 $this->_leftOffset, |
|
269 $this->_topOffset, |
|
270 $this->_leftOffset + $barcodeWidth - 1, |
|
271 $this->_topOffset + $barcodeHeight - 1, |
|
272 $this->_imageBackgroundColor |
|
273 ); |
|
274 } |
|
275 |
|
276 /** |
|
277 * Check barcode parameters |
|
278 * |
|
279 * @return void |
|
280 */ |
|
281 protected function _checkParams() |
|
282 { |
|
283 $this->_checkDimensions(); |
|
284 } |
|
285 |
|
286 /** |
|
287 * Check barcode dimensions |
|
288 * |
|
289 * @return void |
|
290 */ |
|
291 protected function _checkDimensions() |
|
292 { |
|
293 if ($this->_resource !== null) { |
|
294 if (imagesy($this->_resource) < $this->_barcode->getHeight(true)) { |
|
295 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
296 throw new Zend_Barcode_Renderer_Exception( |
|
297 'Barcode is define outside the image (height)' |
|
298 ); |
|
299 } |
|
300 } else { |
|
301 if ($this->_userHeight) { |
|
302 $height = $this->_barcode->getHeight(true); |
|
303 if ($this->_userHeight < $height) { |
|
304 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
305 throw new Zend_Barcode_Renderer_Exception(sprintf( |
|
306 "Barcode is define outside the image (calculated: '%d', provided: '%d')", |
|
307 $height, |
|
308 $this->_userHeight |
|
309 )); |
|
310 } |
|
311 } |
|
312 } |
|
313 if ($this->_resource !== null) { |
|
314 if (imagesx($this->_resource) < $this->_barcode->getWidth(true)) { |
|
315 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
316 throw new Zend_Barcode_Renderer_Exception( |
|
317 'Barcode is define outside the image (width)' |
|
318 ); |
|
319 } |
|
320 } else { |
|
321 if ($this->_userWidth) { |
|
322 $width = $this->_barcode->getWidth(true); |
|
323 if ($this->_userWidth < $width) { |
|
324 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
325 throw new Zend_Barcode_Renderer_Exception(sprintf( |
|
326 "Barcode is define outside the image (calculated: '%d', provided: '%d')", |
|
327 $width, |
|
328 $this->_userWidth |
|
329 )); |
|
330 } |
|
331 } |
|
332 } |
|
333 } |
|
334 |
|
335 /** |
|
336 * Draw and render the barcode with correct headers |
|
337 * |
|
338 * @return mixed |
|
339 */ |
|
340 public function render() |
|
341 { |
|
342 $this->draw(); |
|
343 header("Content-Type: image/" . $this->_imageType); |
|
344 $functionName = 'image' . $this->_imageType; |
|
345 call_user_func($functionName, $this->_resource); |
|
346 @imagedestroy($this->_resource); |
|
347 } |
|
348 |
|
349 /** |
|
350 * Draw a polygon in the image resource |
|
351 * |
|
352 * @param array $points |
|
353 * @param integer $color |
|
354 * @param boolean $filled |
|
355 */ |
|
356 protected function _drawPolygon($points, $color, $filled = true) |
|
357 { |
|
358 $newPoints = array( |
|
359 $points[0][0] + $this->_leftOffset, |
|
360 $points[0][1] + $this->_topOffset, |
|
361 $points[1][0] + $this->_leftOffset, |
|
362 $points[1][1] + $this->_topOffset, |
|
363 $points[2][0] + $this->_leftOffset, |
|
364 $points[2][1] + $this->_topOffset, |
|
365 $points[3][0] + $this->_leftOffset, |
|
366 $points[3][1] + $this->_topOffset, |
|
367 ); |
|
368 |
|
369 $allocatedColor = imagecolorallocate( |
|
370 $this->_resource, |
|
371 ($color & 0xFF0000) >> 16, |
|
372 ($color & 0x00FF00) >> 8, |
|
373 $color & 0x0000FF |
|
374 ); |
|
375 |
|
376 if ($filled) { |
|
377 imagefilledpolygon($this->_resource, $newPoints, 4, $allocatedColor); |
|
378 } else { |
|
379 imagepolygon($this->_resource, $newPoints, 4, $allocatedColor); |
|
380 } |
|
381 } |
|
382 |
|
383 /** |
|
384 * Draw a polygon in the image resource |
|
385 * |
|
386 * @param string $text |
|
387 * @param float $size |
|
388 * @param array $position |
|
389 * @param string $font |
|
390 * @param integer $color |
|
391 * @param string $alignment |
|
392 * @param float $orientation |
|
393 */ |
|
394 protected function _drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0) |
|
395 { |
|
396 $allocatedColor = imagecolorallocate( |
|
397 $this->_resource, |
|
398 ($color & 0xFF0000) >> 16, |
|
399 ($color & 0x00FF00) >> 8, |
|
400 $color & 0x0000FF |
|
401 ); |
|
402 |
|
403 if ($font == null) { |
|
404 $font = 3; |
|
405 } |
|
406 $position[0] += $this->_leftOffset; |
|
407 $position[1] += $this->_topOffset; |
|
408 |
|
409 if (is_numeric($font)) { |
|
410 if ($orientation) { |
|
411 /** |
|
412 * imagestring() doesn't allow orientation, if orientation |
|
413 * needed: a TTF font is required. |
|
414 * Throwing an exception here, allow to use automaticRenderError |
|
415 * to informe user of the problem instead of simply not drawing |
|
416 * the text |
|
417 */ |
|
418 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
419 throw new Zend_Barcode_Renderer_Exception( |
|
420 'No orientation possible with GD internal font' |
|
421 ); |
|
422 } |
|
423 $fontWidth = imagefontwidth($font); |
|
424 $positionY = $position[1] - imagefontheight($font) + 1; |
|
425 switch ($alignment) { |
|
426 case 'left': |
|
427 $positionX = $position[0]; |
|
428 break; |
|
429 case 'center': |
|
430 $positionX = $position[0] - ceil(($fontWidth * strlen($text)) / 2); |
|
431 break; |
|
432 case 'right': |
|
433 $positionX = $position[0] - ($fontWidth * strlen($text)); |
|
434 break; |
|
435 } |
|
436 imagestring($this->_resource, $font, $positionX, $positionY, $text, $color); |
|
437 } else { |
|
438 |
|
439 if (!function_exists('imagettfbbox')) { |
|
440 require_once 'Zend/Barcode/Renderer/Exception.php'; |
|
441 throw new Zend_Barcode_Renderer_Exception( |
|
442 'A font was provided, but this instance of PHP does not have TTF (FreeType) support' |
|
443 ); |
|
444 } |
|
445 |
|
446 $box = imagettfbbox($size, 0, $font, $text); |
|
447 switch ($alignment) { |
|
448 case 'left': |
|
449 $width = 0; |
|
450 break; |
|
451 case 'center': |
|
452 $width = ($box[2] - $box[0]) / 2; |
|
453 break; |
|
454 case 'right': |
|
455 $width = ($box[2] - $box[0]); |
|
456 break; |
|
457 } |
|
458 imagettftext( |
|
459 $this->_resource, |
|
460 $size, |
|
461 $orientation, |
|
462 $position[0] - ($width * cos(pi() * $orientation / 180)), |
|
463 $position[1] + ($width * sin(pi() * $orientation / 180)), |
|
464 $allocatedColor, |
|
465 $font, |
|
466 $text |
|
467 ); |
|
468 } |
|
469 } |
|
470 } |