Webylon 3.1 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • Archive
  • File
  • Filesystem
  • FlushGeneratedImagesTask
  • FLV
  • Folder
  • Folder_UnusedAssetsField
  • GD
  • Image
  • Image_Cached
  • MediawebPage_Image
  • MP3
  • SaveFileSizeTask
  • TarballArchive
  • Upload
  • Upload_Validator
  • VideoFile
  1 <?php
  2 /**
  3  * A wrapper class for GD-based images, with lots of manipulation functions.
  4  * @package sapphire
  5  * @subpackage filesystem
  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         // If we're working with image resampling, things could take a while.  Bump up the time-limit
 15         increase_time_limit_to(300);
 16 
 17         if($filename) {
 18             // We use getimagesize instead of extension checking, because sometimes extensions are wrong.
 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      * Set the default image quality.
 43      * @param quality int A number from 0 to 100, 100 being the best quality.
 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      * Set the image quality, used when saving JPEGs.
 53      */
 54     function setQuality($quality) {
 55         $this->quality = $quality;
 56     }
 57     
 58     /**
 59      * Resize an image to cover the given width/height completely, and crop off any overhanging edges.
 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         // Preserves transparency between images
 70         imagealphablending($newGD, false);
 71         imagesavealpha($newGD, true);
 72         
 73         $destAR = $width / $height;
 74         if ($this->width > 0 && $this->height > 0 ){
 75             // We can't divide by zero theres something wrong.
 76             
 77             $srcAR = $this->width / $this->height;
 78         
 79             // Destination narrower than the source
 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             // Destination shorter than the source
 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      * Resizes the image to fit within the given region.
105      * Behaves similarly to paddedResize but without the padding.
106      * @todo This method isn't very efficent
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      * Resize an image, skewing it as necessary.
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         // Preserves transparency between images
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      * Rotates image by given angle.
149      * 
150      * @param angle 
151      *
152      * @return GD 
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             //imagerotate is not included in PHP included in Ubuntu
162             $newGD = $this->rotatePixelByPixel($angle); 
163         }
164         $output = clone $this;
165         $output->setGD($newGD);
166         return $output;
167     }
168     
169     /**
170      * Rotates image by given angle. It's slow because makes it pixel by pixel rather than
171      * using built-in function. Used when imagerotate function is not available(i.e. Ubuntu)
172      * 
173      * @param angle 
174      *
175      * @return GD 
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      * Crop's part of image.
213      * 
214      * @param top y position of left upper corner of crop rectangle 
215      * @param left x position of left upper corner of crop rectangle
216      * @param width rectangle width
217      * @param height rectangle height
218      *
219      * @return GD  
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      * Method return width of image.
233      *
234      * @return integer width.
235     */ 
236     function getWidth() {
237         return $this->width;
238     }
239     
240     /**
241      * Method return height of image.
242      *
243      * @return integer height 
244     */ 
245     
246     function getHeight() {
247         return $this->height;
248     }
249     
250     /**
251      * Resize an image by width. Preserves aspect ratio.
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      * Resize an image by height. Preserves aspect ratio
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      * Resize the image by preserving aspect ratio. By default, it will keep the image inside the maxWidth and maxHeight
272      * Passing useAsMinimum will make the smaller dimension equal to the maximum corresponding dimension
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      * Resize to fit fully within the given box, without resizing.  Extra space left around
297      * the image will be padded with the background color.
298      * @param width
299      * @param height
300      * @param backgroundColour
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         // Preserves transparency between images
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             // We can't divide by zero theres something wrong.
321             
322             $srcAR = $this->width / $this->height;
323         
324             // Destination narrower than the source
325             if($destAR > $srcAR) {
326                 $destY = 0;
327                 $destHeight = $height;
328                 
329                 $destWidth = $height * $srcAR;
330                 $destX = ($width - $destWidth) / 2;
331             
332             // Destination shorter than the source
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      * Make the image greyscale
350      * $rv = red value, defaults to 38
351      * $gv = green value, defaults to 36
352      * $bv = blue value, defaults to 26
353      * Based (more or less entirely, with changes for readability) on code from http://www.teckis.com/scriptix/thumbnails/teck.html
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             // if the extension does not exist, the file will not be created!
400             
401             switch($type) {
402                 case 1: imagegif($this->gd, $filename); break;
403                 case 2: imagejpeg($this->gd, $filename, $this->quality); break;
404                 
405                 // case 3, and everything else
406                 default: 
407                     // Save them as 8-bit images
408                     // imagetruecolortopalette($this->gd, false, 256);
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. -
Webylon 3.1 API Docs API documentation generated by ApiGen 2.8.0