1 <?php
2 /**
3 * Image.php
4 *
5 * @author Elvyrra SAS
6 * @license http://rem.mit-license.org/ MIT
7 */
8
9 namespace Hawk;
10
11 /**
12 * This class is used to treat images. This class can resize images, or compress them
13 *
14 * @package Utils
15 */
16 abstract class Image{
17 /**
18 * The width of the image
19 */
20 protected $width,
21
22 /**
23 * The height of the image
24 */
25 $height,
26
27 /**
28 * The type of the image : IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_JPEG
29 */
30 $type,
31
32 /**
33 * The mime type of the image
34 */
35 $mime,
36
37 /**
38 * The filename of the image
39 */
40 $filename;
41
42 /**
43 * The allowed types of images
44 */
45 private static $types = array(
46 IMAGETYPE_GIF => 'GifImage',
47 IMAGETYPE_PNG => 'PngImage',
48 IMAGETYPE_JPEG => 'JpegImage'
49 );
50
51
52 /**
53 * Create a new Image instance
54 *
55 * @param string $filename The file path of the image
56 *
57 * @return Image The image instance
58 */
59 public static function getInstance($filename){
60 $info = getimagesize($filename);
61 $data = array(
62 'width' => $info[0],
63 'height' => $info[1],
64 'type' => $info[2],
65 'mime' => $info['mime']
66 );
67 if(!isset(self::$types[$data['type']])) {
68 throw new ImageException("The type of the file $filename is not supported");
69 }
70
71 $class = self::$types[$data['type']];
72 return new $class($filename, $data);
73 }
74
75
76 /**
77 * Constructor
78 *
79 * @param string $filename The file path of the image
80 * @param array $data The data of the file (width, height, type, mime type)
81 */
82 protected function __construct($filename, $data){
83 $this->filename = $filename;
84 foreach($data as $key => $value){
85 $this->$key = $value;
86 }
87 }
88
89 /**
90 * Return the filename of the image
91 *
92 * @return string The file path of the image
93 */
94 public function getFilename(){
95 return $this->filename;
96 }
97
98 /**
99 * Return the width of the image
100 *
101 * @return int The width (in pixels) of the image
102 */
103 public function getWidth(){
104 return $this->width;
105 }
106
107
108 /**
109 * Return the height of the image
110 *
111 * @return int The height (in pixels) if the image
112 */
113 public function getHeight(){
114 return $this->height;
115 }
116
117
118 /**
119 * Return the type of the image
120 *
121 * @return int The type of the image : IMAGETYPE_GIF, IMAGETYPE_PNG, or IMAGETYPE_JPEG
122 */
123 public function getType(){
124 return $this->type;
125 }
126
127
128 /**
129 * Return the mime type of the image
130 *
131 * @return string The mime type of the image
132 */
133 public function getMimeType(){
134 return $this->mime;
135 }
136
137
138 /**
139 * Return the file size of the image
140 *
141 * @return int The file size (in bytes) of the image
142 */
143 public function getFileSize(){
144 return filesize($this->filename);
145 }
146
147
148 /**
149 * Return the file extension of the image, depending on the type of the image, not the image file
150 *
151 * @return string The extension of the image
152 */
153 public function getExtension(){
154 return image_type_to_extension($this->type);
155 }
156
157
158 /**
159 * Resize the image
160 *
161 * @param int $width The new width of the image (in pixels)
162 * @param int $height The new height of the image (in pixels)
163 * @param string $filename The path of the file to save the resized image
164 *
165 * @return Image The new resized image
166 */
167 public function resize($width, $height, $filename){
168 $fs = $this->createResource();
169 $fd = imagecreatetruecolor($width, $height);
170
171 imagecopyresampled($fd, $fs, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
172 $this->save($fd, $filename);
173 return self::getInstance($filename);
174 }
175
176 /**
177 * Compress the image
178 *
179 * @param float $rate The rate compression, between 0 and 1
180 * @param string $filename The path where to save the new compressed file
181 *
182 * @return Image The compressed image
183 */
184 abstract public function compress($rate, $filename);
185 }
186
187
188 /**
189 * This class describes the actions on image specific to PNG images
190 *
191 * @package Utils
192 */
193 class PngImage extends Image{
194 /**
195 * Create a image resource to be treated
196 *
197 * @return resource The created resource
198 */
199 private function createResource(){
200 return imagecreatefrompng($this->filename);
201 }
202
203 /**
204 * Save the image in a file
205 *
206 * @param resource $resource The image resource to save
207 * @param string $filename The file path where to save the image
208 * @param int $compression The compression to apply
209 */
210 private function save($resource, $filename, $compression = 0){
211 imagepng($resource, $filename, $compression);
212 }
213
214
215 /**
216 * Compress the image
217 *
218 * @param float $rate The rate compression, between 0 and 1
219 * @param string $filename The path where to save the new compressed file
220 *
221 * @return Image The compressed image
222 */
223 public function compress($rate, $filename){
224 $fs = $this->createResource();
225 $compression = ceil(-8 / 100 * $rate + 9);
226 $this->save($fs, $filename, $compression);
227 return Image::getInstance($filename);
228 }
229 }
230
231
232
233 /**
234 * This class describes the actions on image specific to JPEG images
235 *
236 * @package Utils
237 */
238 class JpegImage extends Image{
239 /**
240 * Create a image resource to be treated
241 *
242 * @return resource The created resource
243 */
244 private function createResource(){
245 return imagecreatefromjpeg($this->filename);
246 }
247
248
249 /**
250 * Save the image in a file
251 *
252 * @param resource $resource The image resource to save
253 * @param string $filename The file path where to save the image
254 * @param int $quality The quality to apply
255 */
256 private function save($resource, $filename, $quality = 100){
257 imagejpeg($resource, $filename, $quality);
258 }
259
260
261 /**
262 * Compress the image
263 *
264 * @param float $rate The rate compression, between 0 and 1
265 * @param string $filename The path where to save the new compressed file
266 *
267 * @return Image The compressed image
268 */
269 public function compress($rate, $filename){
270 $fs = $this->createResource();
271 $quality = 100 - $rate;
272 $this->save($fs, $filename, $quality);
273
274 return Image::getInstance($filename);
275 }
276 }
277
278
279
280 /**
281 * This class describes the actions on image specific to GIF images
282 *
283 * @package Utils
284 */
285 class GifImage extends Image{
286 /**
287 * Create a image resource to be treated
288 *
289 * @return resource The created resource
290 */
291 private function createResource(){
292 return imagecreatefromgif($this->filename);
293 }
294
295 /**
296 * Save the image in a file
297 *
298 * @param resource $resource The image resource to save
299 * @param string $filename The file path where to save the image
300 */
301 private function save($resource, $filename){
302 imagegif($resource, $filename);
303 }
304
305
306 /**
307 * Compress the image
308 *
309 * @param float $rate The rate compression, between 0 and 1
310 * @param string $filename The path where to save the new compressed file
311 *
312 * @return Image The compressed image
313 */
314 public function compress($rate, $filename){
315 $fs = $this->createResource();
316 $this->save($fs, $filename);
317 return Image::getInstance($filename);
318 }
319 }
320
321 /**
322 * This class describes the execptions throwed by Image class
323 *
324 * @package Exceptions
325 */
326 class ImageException extends \Exception{
327
328 }