Development

/plugins/sfFilebasePlugin/lib/sfFilebasePluginGfxEditorAdapterGD.php

You must first sign up to be able to contribute.

root/plugins/sfFilebasePlugin/lib/sfFilebasePluginGfxEditorAdapterGD.php

Revision 18270, 8.5 kB (checked in by joshiausdemwald, 4 years ago)

Docs on imagefunctions and preserveTransparency for GD thumbnails

Line 
1 <?php
2 /**
3  * This file is part of the sfFilebasePlugin package.
4  *
5  * For the full copyright and license information, please view the LICENSE
6  * file that was distributed with this source code.
7  *
8  * @package   de.optimusprime.sfFilebasePlugin
9  * @author    Johannes Heinen <johannes.heinen@gmail.com>
10  * @license   MIT license
11  * @copyright 2007-2009 Johannes Heinen <johannes.heinen@gmail.com>
12  */
13
14 /**
15  * Adapter for transforming images using the gd1/2 library
16  *
17  * @todo       Implement improved image editing capabilities.
18  */
19 class sfFilebasePluginGfxEditorAdapterGD implements sfFilebasePluginGfxEditorAdapterInterface
20 {
21   /**
22    * @var sfFilebasePluginImage $image
23    */
24   protected $source;
25
26   /**
27    *
28    * @var sfFilebasePluginImage $image
29    */
30   protected $destination;
31
32   /**
33    * @var resource $resource;
34    */
35   protected $source_resource;
36
37   /**
38    * @var resource $resource
39    */
40   protected $destination_resource;
41
42   /**
43    * Reference to editor.
44    *
45    * @var sfFilebasePluginGfxEditor $editor
46    */
47   protected $gfxEditor;
48
49   /**
50    * @var integer Quality in %
51    */
52   protected $destinationQuality = 80;
53  
54   /**
55    * Compatibility layer to switch on the fly between
56    * gd versions.
57    * @var array $funcs
58    */
59   protected $funcs = array();
60
61   /**
62    * If set to true, transparent images will not loose their transparent
63    * color definition during processing
64    *
65    * @var boolean $preserve_transparency
66    */
67   protected $preserve_transparency;
68
69   /**
70    * @param sfFilebasePluginGfxEditor $editor
71    */
72   public function initialize(sfFilebasePluginGfxEditor $gfxEditor)
73   {
74     $this->funcs['imagecreatefromtruecolor'] = function_exists('imagecreatefromtruecolor') ?
75       'imagecreatefromtruecolor' :
76       'imagecreate';
77     $this->funcs['imagecopyresampled'] = function_exists('imagecopyresampled') ?
78       'imagecopyresampled' :
79       'imagecopyresized';
80     $this->gfxEditor = $gfxEditor;
81   }
82
83   /**
84    *
85    * @return boolean true if platform supports gd
86    */
87   public function isSupported()
88   {
89     return extension_loaded('gd');
90   }
91
92   /**
93    * @param FimebaseImage $image
94    */
95   public function setSource(sfFilebasePluginImage $source)
96   {
97     $this->source = $source;
98     switch($source->getMimeType())
99     {
100       case 'image/pjpeg':
101       case 'image/jpeg':
102         $this->source_resource = imagecreatefromjpeg($this->source->getPathname());
103         return;
104       case 'image/gif':
105         $this->source_resource = imagecreatefromgif($this->source->getPathname());
106         return;
107       case 'image/x-png':
108       case 'image/png':
109         $this->source_resource = imagecreatefrompng($this->source->getPathname());
110         return;
111     }
112   }
113
114   /**
115    * Sets the destination quality.
116    * @param integer $quality
117    */
118   public function setQuality($quality)
119   {
120     $this->destinationQuality = $quality;
121   }
122
123   /**
124    * Sets the destination path.
125   
126    * @param sfFilebasePluginImage $destination
127    */
128   public function setDestination(sfFilebasePluginImage $destination)
129   {
130     $this->destination = $destination;
131   }
132
133   /**
134    * Saves the image as destination path name to disc.
135    *
136    * @param integer $chmod
137    * @return sfFilebasePluginImage $destination
138    */
139   public function save($chmod = 0777)
140   {
141     if(!is_resource($this->destination_resource)) throw new sfFilebasePluginException('Nothing to save.');
142     switch($this->destination->getMimeType())
143     {
144       case 'image/pjpeg':
145       case 'image/jpeg':
146         imagejpeg($this->destination_resource, $this->destination->getPathname(), $this->destinationQuality);
147         break;
148       case 'image/gif':
149         imagegif($this->destination_resource, $this->destination->getPathname());
150         break;
151       case 'image/x-png':
152       case 'image/png':
153         imagepng($this->destination_resource, $this->destination->getPathname(), round($this->destinationQuality/10), PNG_ALL_FILTERS);
154         break;
155     }
156     $this->destination->chmod($chmod);
157     return $this->destination;
158   }
159
160   /**
161    * Frees memory that was reserved for image
162    * manipulation.
163    */
164   public function destroy()
165   {
166     imagedestroy($this->destination_resource);
167     imagedestroy($this->source_resource);
168     $this->destination_resource  = null;
169     $this->target_resource       = null;
170     $this->destination            = null;
171     $this->source                 = null;
172   }
173
174   /**
175    * Resizes the source image.
176    *
177    * Uses some ideas from Adrian Mummey
178    * <http://www.mummey.org/2008/11/transparent-gifs-with-php-and-gd/comment-page-1/#comment-264>
179    * to preserve transparent color on gifs images.
180    *
181    * @param array $dimensions
182    * @return boolean true if image resizing was successful
183    */
184   public function resize(array $dimensions)
185   {
186     if(!is_resource($this->source_resource) || !$this->destination instanceof sfFilebasePluginImage) throw new sfFilebasePluginException('You must set a source and a destination image to resize.');
187     
188     $image_data = $this->gfxEditor->getScaledImageData($this->source, $dimensions);
189
190     $width                = $image_data['orig_width'];
191     $height               = $image_data['orig_height'];
192     $new_width            = $image_data['new_width'];
193     $new_height           = $image_data['new_height'];
194     $mime                 = $image_data['mime'];
195
196     $this->destination_resource = imagecreatetruecolor($new_width, $new_height);
197
198     if($this->preserve_transparency && ($mime == 'image/gif' || $mime == 'image/png' || $mime == 'image/x-png'))
199     {
200       if($mime == 'image/gif')
201       {
202         imagealphablending($this->destination_resource, false);
203         $transparent1 = imagecolorallocatealpha($this->destination_resource, 255, 255, 255, 127);
204         imagefilledrectangle($this->destination_resource, 0, 0, $new_width, $new_height, $transparent1);
205         imagecolortransparent($this->destination_resource, $transparent1);
206       }
207       else
208       {
209         imagealphablending($this->destination_resource, false);
210       }
211       imagesavealpha($this->destination_resource, true);
212       switch ($mime)
213       {
214         case 'image/png':
215         case 'image/x-png':
216           $this->funcs['imagecopyresampled']($this->destination_resource, $this->source_resource, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
217           break;
218         case 'image/gif':
219           imagecopyresized($this->destination_resource, $this->source_resource, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
220           break;
221       }
222     }
223     else
224     {
225       switch ($mime)
226       {
227         case  'image/jpeg':
228         case  'image/pjpeg':
229           $this->funcs['imagecopyresampled']($this->destination_resource, $this->source_resource, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
230           break;
231         case 'image/x-png':
232         case 'image/png':
233           $this->funcs['imagecopyresampled']($this->destination_resource, $this->source_resource, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
234           break;
235         case 'image/gif':
236           $this->funcs['imagecopyresampled']($this->destination_resource, $this->source_resource, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
237           break;
238       }
239     }
240     return true;
241   }
242
243   /**
244    * Rotates an image to $deg degree
245    *
246    * @uses  imagerotate():     Hinweis: Diese Funktion steht nur zur Verfügung, wenn PHP mit der GD Bibliothek übersetzt wurde, die mit PHP zusammen erhältlich ist.
247    * @todo Implement fallback. Its a performance issue.
248    * @experimental
249    * @param float  $deg: The amount to rotate
250    * @param string $bgcolor: The background color in html hexadecimal notation
251    * @return sfFilebasePluginImage $image: THe rotated image
252    */
253   public function rotate($deg$bgcolor)
254   {
255     $bgcolor=0;
256     if(!function_exists('imagerotate')) throw new sfFilebasePluginException('Imagerotate() is not supported by your gd-version, you must compile php with the pre-built gd2-library.');
257     if(!is_resource($this->source_resource) || !$this->destination instanceof sfFilebasePluginImage) throw new sfFilebasePluginException('You must set a source and a destination image to resize.');
258     $this->destination_resource = imagerotate($this->source_resource, $deg, sfFilebasePluginUtil::parseHTMLColor($bgcolor), true);
259     if(!is_resource($this->destination_resource)) throw new sfFilebasePluginException(sprintf('Failed to rotate image %s.', $this->source));
260     return true;
261   }
262
263   /**
264    * Sets the flag that determins if the processor should preserve transparency
265    * during the image manipulation.
266    *
267    * @param boolean $preserve_transparency
268    */
269   public function setPreserveTransparency($preserve_transparency)
270   {
271     $this->preserve_transparency = $preserve_transparency;
272   }
273 }
Note: See TracBrowser for help on using the browser.