1 <?php
2 3 4 5 6
7 class GD extends Object {
8 protected $gd, $width, $height;
9 protected $quality;
10
11 protected static $default_quality = 75;
12
13 function __construct($filename = null) {
14
15 increase_time_limit_to(300);
16
17 if($filename) {
18
19 @list($width, $height, $type, $attr) = getimagesize($filename);
20 switch($type) {
21 case 1: if(function_exists('imagecreatefromgif')) $this->setGD(@imagecreatefromgif($filename)); break;
22 case 2: if(function_exists('imagecreatefromjpeg')) $this->setGD(@imagecreatefromjpeg($filename)); break;
23 case 3: if(function_exists('imagecreatefrompng')) $this->setGD(@imagecreatefrompng($filename)); break;
24 }
25 }
26
27 $this->quality = self::$default_quality;
28 parent::__construct();
29 }
30 public function setGD($gd) {
31 $this->gd = $gd;
32 $this->width = imagesx($gd);
33 $this->height = imagesy($gd);
34 }
35
36 public function getGD() {
37 return $this->gd;
38 }
39
40
41 42 43 44
45 static function set_default_quality($quality) {
46 if(is_numeric($quality) && (int) $quality >= 0 && (int) $quality <= 100) {
47 self::$default_quality = (int) $quality;
48 }
49 }
50
51 52 53
54 function setQuality($quality) {
55 $this->quality = $quality;
56 }
57
58 59 60
61 function croppedResize($width, $height) {
62 if(!$this->gd) return;
63
64 $width = round($width);
65 $height = round($height);
66
67 $newGD = imagecreatetruecolor($width, $height);
68
69
70 imagealphablending($newGD, false);
71 imagesavealpha($newGD, true);
72
73 $destAR = $width / $height;
74 if ($this->width > 0 && $this->height > 0 ){
75
76
77 $srcAR = $this->width / $this->height;
78
79
80 if($destAR < $srcAR) {
81 $srcY = 0;
82 $srcHeight = $this->height;
83
84 $srcWidth = $this->height * $destAR;
85 $srcX = ($this->width - $srcWidth) / 2;
86
87
88 } else {
89 $srcX = 0;
90 $srcWidth = $this->width;
91
92 $srcHeight = $this->width / $destAR;
93 $srcY = ($this->height - $srcHeight) / 2;
94 }
95
96 imagecopyresampled($newGD, $this->gd, 0,0, $srcX, $srcY, $width, $height, $srcWidth, $srcHeight);
97 }
98 $output = clone $this;
99 $output->setGD($newGD);
100 return $output;
101 }
102
103 104 105 106 107
108 function fittedResize($width, $height) {
109 $gd = $this->resizeByHeight($height);
110 if($gd->width > $width) $gd = $gd->resizeByWidth($width);
111 return $gd;
112 }
113
114 function hasGD() {
115 return $this->gd ? true : false;
116 }
117
118
119 120 121
122 function resize($width, $height) {
123 if(!$this->gd) return;
124
125 $width = round($width);
126 $height = round($height);
127 if(!$width && !$height) user_error("No dimensions given", E_USER_ERROR);
128 if(!$width) user_error("Width not given", E_USER_ERROR);
129 if(!$height) user_error("Height not given", E_USER_ERROR);
130
131 if ($this->width == $width && $this->height == $height)
132 return clone $this;
133
134 $newGD = imagecreatetruecolor($width, $height);
135
136
137 imagealphablending($newGD, false);
138 imagesavealpha($newGD, true);
139
140 imagecopyresampled($newGD, $this->gd, 0,0, 0, 0, $width, $height, $this->width, $this->height);
141
142 $output = clone $this;
143 $output->setGD($newGD);
144 return $output;
145 }
146
147 148 149 150 151 152 153
154
155 function rotate($angle) {
156 if(!$this->gd) return;
157
158 if(function_exists("imagerotate")) {
159 $newGD = imagerotate($this->gd, $angle,0);
160 } else {
161
162 $newGD = $this->rotatePixelByPixel($angle);
163 }
164 $output = clone $this;
165 $output->setGD($newGD);
166 return $output;
167 }
168
169 170 171 172 173 174 175 176
177
178 function rotatePixelByPixel($angle) {
179 $sourceWidth = imagesx($this->gd);
180 $sourceHeight = imagesy($this->gd);
181 if ($angle == 180) {
182 $destWidth = $sourceWidth;
183 $destHeight = $sourceHeight;
184 } else {
185 $destWidth = $sourceHeight;
186 $destHeight = $sourceWidth;
187 }
188 $rotate=imagecreatetruecolor($destWidth,$destHeight);
189 imagealphablending($rotate, false);
190 for ($x = 0; $x < ($sourceWidth); $x++) {
191 for ($y = 0; $y < ($sourceHeight); $y++) {
192 $color = imagecolorat($this->gd, $x, $y);
193 switch ($angle) {
194 case 90:
195 imagesetpixel($rotate, $y, $destHeight - $x - 1, $color);
196 break;
197 case 180:
198 imagesetpixel($rotate, $destWidth - $x - 1, $destHeight - $y - 1, $color);
199 break;
200 case 270:
201 imagesetpixel($rotate, $destWidth - $y - 1, $x, $color);
202 break;
203 default: $rotate = $this->gd;
204 };
205 }
206 }
207 return $rotate;
208 }
209
210
211 212 213 214 215 216 217 218 219 220
221
222 function crop($top, $left, $width, $height) {
223 $newGD = imagecreatetruecolor($width, $height);
224 imagecopyresampled($newGD, $this->gd, 0, 0, $left, $top, $width, $height, $width, $height);
225
226 $output = clone $this;
227 $output->setGD($newGD);
228 return $output;
229 }
230
231 232 233 234 235
236 function getWidth() {
237 return $this->width;
238 }
239
240 241 242 243 244
245
246 function getHeight() {
247 return $this->height;
248 }
249
250 251 252
253 function resizeByWidth( $width ) {
254 if (round($width) == $this->width)
255 return clone $this;
256 $heightScale = $width / $this->width;
257 return $this->resize( $width, $heightScale * $this->height );
258 }
259
260 261 262
263 function resizeByHeight( $height ) {
264 if (round($height) == $this->height)
265 return clone $this;
266 $scale = $height / $this->height;
267 return $this->resize( $scale * $this->width, $height );
268 }
269
270 271 272 273
274 function resizeRatio( $maxWidth, $maxHeight, $useAsMinimum = false ) {
275
276 $widthRatio = $maxWidth / $this->width;
277 $heightRatio = $maxHeight / $this->height;
278
279 if( $widthRatio < $heightRatio )
280 return $useAsMinimum ? $this->resizeByHeight( $maxHeight ) : $this->resizeByWidth( $maxWidth );
281 else
282 return $useAsMinimum ? $this->resizeByWidth( $maxWidth ) : $this->resizeByHeight( $maxHeight );
283 }
284
285 static function color_web2gd($image, $webColor) {
286 if(substr($webColor,0,1) == "#") $webColor = substr($webColor,1);
287 $r = hexdec(substr($webColor,0,2));
288 $g = hexdec(substr($webColor,2,2));
289 $b = hexdec(substr($webColor,4,2));
290
291 return imagecolorallocate($image, $r, $g, $b);
292
293 }
294
295 296 297 298 299 300 301
302 function paddedResize($width, $height, $backgroundColor = "FFFFFF") {
303 if(!$this->gd) return;
304
305 $width = round($width);
306 $height = round($height);
307
308
309 $newGD = imagecreatetruecolor($width, $height);
310
311
312 imagealphablending($newGD, false);
313 imagesavealpha($newGD, true);
314
315 $bg = GD::color_web2gd($newGD, $backgroundColor);
316 imagefilledrectangle($newGD, 0, 0, $width, $height, $bg);
317
318 $destAR = $width / $height;
319 if ($this->width > 0 && $this->height > 0) {
320
321
322 $srcAR = $this->width / $this->height;
323
324
325 if($destAR > $srcAR) {
326 $destY = 0;
327 $destHeight = $height;
328
329 $destWidth = $height * $srcAR;
330 $destX = ($width - $destWidth) / 2;
331
332
333 } else {
334 $destX = 0;
335 $destWidth = $width;
336
337 $destHeight = $width / $srcAR;
338 $destY = ($height - $destHeight) / 2;
339 }
340
341 imagecopyresampled($newGD, $this->gd, $destX, $destY, 0, 0, $destWidth, $destHeight, $this->width, $this->height);
342 }
343 $output = clone $this;
344 $output->setGD($newGD);
345 return $output;
346 }
347
348 349 350 351 352 353 354
355 function greyscale($rv=38, $gv=36, $bv=26) {
356 $width = $this->width;
357 $height = $this->height;
358 $newGD = imagecreatetruecolor($this->width, $this->height);
359
360 $rt = $rv + $bv + $gv;
361 $rr = ($rv == 0) ? 0 : 1/($rt/$rv);
362 $br = ($bv == 0) ? 0 : 1/($rt/$bv);
363 $gr = ($gv == 0) ? 0 : 1/($rt/$gv);
364 for($dy = 0; $dy < $height; $dy++) {
365 for($dx = 0; $dx < $width; $dx++) {
366 $pxrgb = imagecolorat($this->gd, $dx, $dy);
367 $heightgb = ImageColorsforIndex($this->gd, $pxrgb);
368 $newcol = ($rr*$heightgb['red']) + ($br*$heightgb['blue']) + ($gr*$heightgb['green']);
369 $setcol = ImageColorAllocate($newGD, $newcol, $newcol, $newcol);
370 imagesetpixel($newGD, $dx, $dy, $setcol);
371 }
372 }
373
374 $output = clone $this;
375 $output->setGD($newGD);
376 return $output;
377 }
378
379 function makeDir($dirname) {
380 if(!file_exists(dirname($dirname))) $this->makeDir(dirname($dirname));
381 if(!file_exists($dirname)) mkdir($dirname, Filesystem::$folder_create_mask);
382 }
383
384 function writeTo($filename) {
385 $this->makeDir(dirname($filename));
386
387 if($filename) {
388 if(file_exists($filename)) list($width, $height, $type, $attr) = getimagesize($filename);
389
390 if(file_exists($filename)) unlink($filename);
391
392 $ext = strtolower(substr($filename, strrpos($filename,'.')+1));
393 if(!isset($type)) switch($ext) {
394 case "gif": $type = 1; break;
395 case "jpeg": case "jpg": case "jpe": $type = 2; break;
396 default: $type = 3; break;
397 }
398
399
400
401 switch($type) {
402 case 1: imagegif($this->gd, $filename); break;
403 case 2: imagejpeg($this->gd, $filename, $this->quality); break;
404
405
406 default:
407
408
409 imagepng($this->gd, $filename); break;
410 }
411 if(file_exists($filename)) @chmod($filename,0664);
412 }
413 }
414
415 }
416
417 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-