192a8473aSAndreas Gohr<?php /** @noinspection PhpComposerExtensionStubsInspection */ 292a8473aSAndreas Gohr 392a8473aSAndreas Gohr 492a8473aSAndreas Gohrnamespace splitbrain\slika; 592a8473aSAndreas Gohr 65c25a071SAndreas Gohr/** 75c25a071SAndreas Gohr * Image processing adapter for PHP's libGD 85c25a071SAndreas Gohr */ 992a8473aSAndreas Gohrclass GdAdapter extends Adapter 1092a8473aSAndreas Gohr{ 1192a8473aSAndreas Gohr /** @var resource libGD image */ 1292a8473aSAndreas Gohr protected $image; 1392a8473aSAndreas Gohr /** @var int width of the current image */ 1492a8473aSAndreas Gohr protected $width = 0; 1592a8473aSAndreas Gohr /** @var int height of the current image */ 1692a8473aSAndreas Gohr protected $height = 0; 1792a8473aSAndreas Gohr /** @var string the extension of the file we're working with */ 1892a8473aSAndreas Gohr protected $extension; 1992a8473aSAndreas Gohr 2092a8473aSAndreas Gohr 2192a8473aSAndreas Gohr /** @inheritDoc */ 2292a8473aSAndreas Gohr public function __construct($imagepath, $options = []) 2392a8473aSAndreas Gohr { 2492a8473aSAndreas Gohr parent::__construct($imagepath, $options); 2592a8473aSAndreas Gohr $this->image = $this->loadImage($imagepath); 2692a8473aSAndreas Gohr } 2792a8473aSAndreas Gohr 2892a8473aSAndreas Gohr /** 2992a8473aSAndreas Gohr * Clean up 3092a8473aSAndreas Gohr */ 3192a8473aSAndreas Gohr public function __destruct() 3292a8473aSAndreas Gohr { 3392a8473aSAndreas Gohr if (is_resource($this->image)) { 3492a8473aSAndreas Gohr imagedestroy($this->image); 3592a8473aSAndreas Gohr } 3692a8473aSAndreas Gohr } 3792a8473aSAndreas Gohr 3892a8473aSAndreas Gohr /** @inheritDoc 3992a8473aSAndreas Gohr * @throws Exception 4092a8473aSAndreas Gohr * @link https://gist.github.com/EionRobb/8e0c76178522bc963c75caa6a77d3d37#file-imagecreatefromstring_autorotate-php-L15 4192a8473aSAndreas Gohr */ 4292a8473aSAndreas Gohr public function autorotate() 4392a8473aSAndreas Gohr { 4492a8473aSAndreas Gohr if ($this->extension !== 'jpeg') { 4592a8473aSAndreas Gohr return $this; 4692a8473aSAndreas Gohr } 4792a8473aSAndreas Gohr 4892a8473aSAndreas Gohr $orientation = 1; 4992a8473aSAndreas Gohr 5092a8473aSAndreas Gohr if (function_exists('exif_read_data')) { 5192a8473aSAndreas Gohr // use PHP's exif capablities 5292a8473aSAndreas Gohr $exif = exif_read_data($this->imagepath); 5392a8473aSAndreas Gohr if (!empty($exif['Orientation'])) { 5492a8473aSAndreas Gohr $orientation = $exif['Orientation']; 5592a8473aSAndreas Gohr } 5692a8473aSAndreas Gohr } else { 5792a8473aSAndreas Gohr // grep the exif info from the raw contents 5892a8473aSAndreas Gohr // we read only the first 70k bytes 5992a8473aSAndreas Gohr $data = file_get_contents($this->imagepath, false, null, 0, 70000); 6092a8473aSAndreas Gohr if (preg_match('@\x12\x01\x03\x00\x01\x00\x00\x00(.)\x00\x00\x00@', $data, $matches)) { 6192a8473aSAndreas Gohr // Little endian EXIF 6292a8473aSAndreas Gohr $orientation = ord($matches[1]); 6392a8473aSAndreas Gohr } else if (preg_match('@\x01\x12\x00\x03\x00\x00\x00\x01\x00(.)\x00\x00@', $data, $matches)) { 6492a8473aSAndreas Gohr // Big endian EXIF 6592a8473aSAndreas Gohr $orientation = ord($matches[1]); 6692a8473aSAndreas Gohr } 6792a8473aSAndreas Gohr } 6892a8473aSAndreas Gohr 6992a8473aSAndreas Gohr return $this->rotate($orientation); 7092a8473aSAndreas Gohr } 7192a8473aSAndreas Gohr 7292a8473aSAndreas Gohr /** 7392a8473aSAndreas Gohr * @inheritDoc 7492a8473aSAndreas Gohr * @throws Exception 7592a8473aSAndreas Gohr */ 7692a8473aSAndreas Gohr public function rotate($orientation) 7792a8473aSAndreas Gohr { 7892a8473aSAndreas Gohr $orientation = (int)$orientation; 7992a8473aSAndreas Gohr if ($orientation < 0 || $orientation > 8) { 8092a8473aSAndreas Gohr throw new Exception('Unknown rotation given'); 8192a8473aSAndreas Gohr } 8292a8473aSAndreas Gohr 8392a8473aSAndreas Gohr if ($orientation <= 1) { 8492a8473aSAndreas Gohr // no rotation wanted 8592a8473aSAndreas Gohr return $this; 8692a8473aSAndreas Gohr } 8792a8473aSAndreas Gohr 8892a8473aSAndreas Gohr // fill color 8992a8473aSAndreas Gohr $transparency = imagecolorallocatealpha($this->image, 0, 0, 0, 127); 9092a8473aSAndreas Gohr 9192a8473aSAndreas Gohr // rotate 9292a8473aSAndreas Gohr if (in_array($orientation, [3, 4])) { 9392a8473aSAndreas Gohr $image = imagerotate($this->image, 180, $transparency, 1); 9492a8473aSAndreas Gohr } 9592a8473aSAndreas Gohr if (in_array($orientation, [5, 6])) { 9692a8473aSAndreas Gohr $image = imagerotate($this->image, -90, $transparency, 1); 9792a8473aSAndreas Gohr list($this->width, $this->height) = [$this->height, $this->width]; 9892a8473aSAndreas Gohr } elseif (in_array($orientation, [7, 8])) { 9992a8473aSAndreas Gohr $image = imagerotate($this->image, 90, $transparency, 1); 10092a8473aSAndreas Gohr list($this->width, $this->height) = [$this->height, $this->width]; 10192a8473aSAndreas Gohr } 10292a8473aSAndreas Gohr /** @var resource $image is now defined */ 10392a8473aSAndreas Gohr 10492a8473aSAndreas Gohr // additionally flip 10592a8473aSAndreas Gohr if (in_array($orientation, [2, 5, 7, 4])) { 10692a8473aSAndreas Gohr imageflip($image, IMG_FLIP_HORIZONTAL); 10792a8473aSAndreas Gohr } 10892a8473aSAndreas Gohr 10992a8473aSAndreas Gohr imagedestroy($this->image); 11092a8473aSAndreas Gohr $this->image = $image; 11192a8473aSAndreas Gohr 11292a8473aSAndreas Gohr //keep png alpha channel if possible 11392a8473aSAndreas Gohr if ($this->extension == 'png' && function_exists('imagesavealpha')) { 11492a8473aSAndreas Gohr imagealphablending($this->image, false); 11592a8473aSAndreas Gohr imagesavealpha($this->image, true); 11692a8473aSAndreas Gohr } 11792a8473aSAndreas Gohr 11892a8473aSAndreas Gohr return $this; 11992a8473aSAndreas Gohr } 12092a8473aSAndreas Gohr 12192a8473aSAndreas Gohr /** 12292a8473aSAndreas Gohr * @inheritDoc 12392a8473aSAndreas Gohr * @throws Exception 12492a8473aSAndreas Gohr */ 12592a8473aSAndreas Gohr public function resize($width, $height) 12692a8473aSAndreas Gohr { 12792a8473aSAndreas Gohr list($width, $height) = $this->boundingBox($width, $height); 12892a8473aSAndreas Gohr $this->resizeOperation($width, $height); 12992a8473aSAndreas Gohr return $this; 13092a8473aSAndreas Gohr } 13192a8473aSAndreas Gohr 13292a8473aSAndreas Gohr /** 13392a8473aSAndreas Gohr * @inheritDoc 13492a8473aSAndreas Gohr * @throws Exception 13592a8473aSAndreas Gohr */ 13692a8473aSAndreas Gohr public function crop($width, $height) 13792a8473aSAndreas Gohr { 13892a8473aSAndreas Gohr list($this->width, $this->height, $offsetX, $offsetY) = $this->cropPosition($width, $height); 13992a8473aSAndreas Gohr $this->resizeOperation($width, $height, $offsetX, $offsetY); 14092a8473aSAndreas Gohr return $this; 14192a8473aSAndreas Gohr } 14292a8473aSAndreas Gohr 14392a8473aSAndreas Gohr /** 14492a8473aSAndreas Gohr * @inheritDoc 14592a8473aSAndreas Gohr * @throws Exception 14692a8473aSAndreas Gohr */ 14792a8473aSAndreas Gohr public function save($path, $extension = '') 14892a8473aSAndreas Gohr { 14992a8473aSAndreas Gohr if ($extension === 'jpg') { 15092a8473aSAndreas Gohr $extension = 'jpeg'; 15192a8473aSAndreas Gohr } 15292a8473aSAndreas Gohr if ($extension === '') { 15392a8473aSAndreas Gohr $extension = $this->extension; 15492a8473aSAndreas Gohr } 15592a8473aSAndreas Gohr $saver = 'image' . $extension; 15692a8473aSAndreas Gohr if (!function_exists($saver)) { 15792a8473aSAndreas Gohr throw new Exception('Can not save image format ' . $extension); 15892a8473aSAndreas Gohr } 15992a8473aSAndreas Gohr 16092a8473aSAndreas Gohr if ($extension == 'jpeg') { 16192a8473aSAndreas Gohr imagejpeg($this->image, $path, $this->options['quality']); 16292a8473aSAndreas Gohr } else { 16392a8473aSAndreas Gohr $saver($this->image, $path); 16492a8473aSAndreas Gohr } 16592a8473aSAndreas Gohr 16692a8473aSAndreas Gohr imagedestroy($this->image); 16792a8473aSAndreas Gohr } 16892a8473aSAndreas Gohr 16992a8473aSAndreas Gohr /** 17092a8473aSAndreas Gohr * Initialize libGD on the given image 17192a8473aSAndreas Gohr * 17292a8473aSAndreas Gohr * @param string $path 17392a8473aSAndreas Gohr * @return resource 17492a8473aSAndreas Gohr * @throws Exception 17592a8473aSAndreas Gohr */ 17692a8473aSAndreas Gohr protected function loadImage($path) 17792a8473aSAndreas Gohr { 17892a8473aSAndreas Gohr // Figure out the file info 17992a8473aSAndreas Gohr $info = getimagesize($path); 18092a8473aSAndreas Gohr if ($info === false) { 18192a8473aSAndreas Gohr throw new Exception('Failed to read image information'); 18292a8473aSAndreas Gohr } 18392a8473aSAndreas Gohr $this->width = $info[0]; 18492a8473aSAndreas Gohr $this->height = $info[1]; 18592a8473aSAndreas Gohr 18692a8473aSAndreas Gohr // what type of image is it? 18792a8473aSAndreas Gohr $this->extension = image_type_to_extension($info[2], false); 18892a8473aSAndreas Gohr $creator = 'imagecreatefrom' . $this->extension; 18992a8473aSAndreas Gohr if (!function_exists($creator)) { 19092a8473aSAndreas Gohr throw new Exception('Can not work with image format ' . $this->extension); 19192a8473aSAndreas Gohr } 19292a8473aSAndreas Gohr 19392a8473aSAndreas Gohr // create the GD instance 19492a8473aSAndreas Gohr $image = @$creator($path); 19592a8473aSAndreas Gohr 19692a8473aSAndreas Gohr if ($image === false) { 19792a8473aSAndreas Gohr throw new Exception('Failed to load image wiht libGD'); 19892a8473aSAndreas Gohr } 19992a8473aSAndreas Gohr 20092a8473aSAndreas Gohr return $image; 20192a8473aSAndreas Gohr } 20292a8473aSAndreas Gohr 20392a8473aSAndreas Gohr /** 20492a8473aSAndreas Gohr * Creates a new blank image to which we can copy 20592a8473aSAndreas Gohr * 20692a8473aSAndreas Gohr * Tries to set up alpha/transparency stuff correctly 20792a8473aSAndreas Gohr * 20892a8473aSAndreas Gohr * @param int $width 20992a8473aSAndreas Gohr * @param int $height 21092a8473aSAndreas Gohr * @return resource 21192a8473aSAndreas Gohr * @throws Exception 21292a8473aSAndreas Gohr */ 21392a8473aSAndreas Gohr protected function createImage($width, $height) 21492a8473aSAndreas Gohr { 21592a8473aSAndreas Gohr // create a canvas to copy to, use truecolor if possible (except for gif) 21692a8473aSAndreas Gohr $canvas = false; 21792a8473aSAndreas Gohr if (function_exists('imagecreatetruecolor') && $this->extension != 'gif') { 21892a8473aSAndreas Gohr $canvas = @imagecreatetruecolor($width, $height); 21992a8473aSAndreas Gohr } 22092a8473aSAndreas Gohr if (!$canvas) { 22192a8473aSAndreas Gohr $canvas = @imagecreate($width, $height); 22292a8473aSAndreas Gohr } 22392a8473aSAndreas Gohr if (!$canvas) { 22492a8473aSAndreas Gohr throw new Exception('Failed to create new canvas'); 22592a8473aSAndreas Gohr } 22692a8473aSAndreas Gohr 22792a8473aSAndreas Gohr //keep png alpha channel if possible 22892a8473aSAndreas Gohr if ($this->extension == 'png' && function_exists('imagesavealpha')) { 22992a8473aSAndreas Gohr imagealphablending($canvas, false); 23092a8473aSAndreas Gohr imagesavealpha($canvas, true); 23192a8473aSAndreas Gohr } 23292a8473aSAndreas Gohr 23392a8473aSAndreas Gohr //keep gif transparent color if possible 234*2cadabe7SAndreas Gohr if ($this->extension == 'gif') { 235*2cadabe7SAndreas Gohr $this->keepGifTransparency($this->image, $canvas); 236*2cadabe7SAndreas Gohr } 237*2cadabe7SAndreas Gohr 238*2cadabe7SAndreas Gohr return $canvas; 239*2cadabe7SAndreas Gohr } 240*2cadabe7SAndreas Gohr 241*2cadabe7SAndreas Gohr /** 242*2cadabe7SAndreas Gohr * Copy transparency from gif to gif 243*2cadabe7SAndreas Gohr * 244*2cadabe7SAndreas Gohr * If no transparency is found or the PHP does not support it, the canvas is filled with white 245*2cadabe7SAndreas Gohr * 246*2cadabe7SAndreas Gohr * @param resource $image Original image 247*2cadabe7SAndreas Gohr * @param resource $canvas New, empty image 248*2cadabe7SAndreas Gohr * @return void 249*2cadabe7SAndreas Gohr */ 250*2cadabe7SAndreas Gohr protected function keepGifTransparency($image, $canvas) 251*2cadabe7SAndreas Gohr { 252*2cadabe7SAndreas Gohr if (!function_exists('imagefill') || !function_exists('imagecolorallocate')) { 253*2cadabe7SAndreas Gohr return; 254*2cadabe7SAndreas Gohr } 255*2cadabe7SAndreas Gohr 256*2cadabe7SAndreas Gohr try { 257*2cadabe7SAndreas Gohr if (!function_exists('imagecolorsforindex') || !function_exists('imagecolortransparent')) { 258*2cadabe7SAndreas Gohr throw new \Exception('missing alpha methods'); 259*2cadabe7SAndreas Gohr } 260*2cadabe7SAndreas Gohr 261*2cadabe7SAndreas Gohr $transcolorindex = @imagecolortransparent($image); 262*2cadabe7SAndreas Gohr $transcolor = @imagecolorsforindex($image, $transcolorindex); 263*2cadabe7SAndreas Gohr if (!$transcolor) { 264*2cadabe7SAndreas Gohr // pre-PHP8 false is returned, in PHP8 an exception is thrown 265*2cadabe7SAndreas Gohr throw new \ValueError('no valid alpha color'); 266*2cadabe7SAndreas Gohr } 267*2cadabe7SAndreas Gohr 26892a8473aSAndreas Gohr $transcolorindex = @imagecolorallocate( 26992a8473aSAndreas Gohr $canvas, 27092a8473aSAndreas Gohr $transcolor['red'], 27192a8473aSAndreas Gohr $transcolor['green'], 27292a8473aSAndreas Gohr $transcolor['blue'] 27392a8473aSAndreas Gohr ); 27492a8473aSAndreas Gohr @imagefill($canvas, 0, 0, $transcolorindex); 27592a8473aSAndreas Gohr @imagecolortransparent($canvas, $transcolorindex); 27692a8473aSAndreas Gohr 277*2cadabe7SAndreas Gohr } catch (\Throwable $ignored) { 278*2cadabe7SAndreas Gohr //filling with white 279*2cadabe7SAndreas Gohr $whitecolorindex = @imagecolorallocate($canvas, 255, 255, 255); 280*2cadabe7SAndreas Gohr @imagefill($canvas, 0, 0, $whitecolorindex); 281*2cadabe7SAndreas Gohr } 28292a8473aSAndreas Gohr } 28392a8473aSAndreas Gohr 28492a8473aSAndreas Gohr /** 28592a8473aSAndreas Gohr * Calculate new size 28692a8473aSAndreas Gohr * 28792a8473aSAndreas Gohr * If widht and height are given, the new size will be fit within this bounding box. 28892a8473aSAndreas Gohr * If only one value is given the other is adjusted to match according to the aspect ratio 28992a8473aSAndreas Gohr * 29092a8473aSAndreas Gohr * @param int $width width of the bounding box 29192a8473aSAndreas Gohr * @param int $height height of the bounding box 29292a8473aSAndreas Gohr * @return array (width, height) 29392a8473aSAndreas Gohr * @throws Exception 29492a8473aSAndreas Gohr */ 29592a8473aSAndreas Gohr protected function boundingBox($width, $height) 29692a8473aSAndreas Gohr { 2976cb05674SAndreas Gohr $width = $this->cleanDimension($width, $this->width); 2986cb05674SAndreas Gohr $height = $this->cleanDimension($height, $this->height); 2996cb05674SAndreas Gohr 30092a8473aSAndreas Gohr if ($width == 0 && $height == 0) { 30192a8473aSAndreas Gohr throw new Exception('You can not resize to 0x0'); 30292a8473aSAndreas Gohr } 30392a8473aSAndreas Gohr 30492a8473aSAndreas Gohr if (!$height) { 30592a8473aSAndreas Gohr // adjust to match width 30692a8473aSAndreas Gohr $height = round(($width * $this->height) / $this->width); 30792a8473aSAndreas Gohr } else if (!$width) { 30892a8473aSAndreas Gohr // adjust to match height 30992a8473aSAndreas Gohr $width = round(($height * $this->width) / $this->height); 31092a8473aSAndreas Gohr } else { 31192a8473aSAndreas Gohr // fit into bounding box 31292a8473aSAndreas Gohr $scale = min($width / $this->width, $height / $this->height); 31392a8473aSAndreas Gohr $width = $this->width * $scale; 31492a8473aSAndreas Gohr $height = $this->height * $scale; 31592a8473aSAndreas Gohr } 31692a8473aSAndreas Gohr 31792a8473aSAndreas Gohr return [$width, $height]; 31892a8473aSAndreas Gohr } 31992a8473aSAndreas Gohr 32092a8473aSAndreas Gohr /** 3216cb05674SAndreas Gohr * Ensure the given Dimension is a proper pixel value 3226cb05674SAndreas Gohr * 3236cb05674SAndreas Gohr * When a percentage is given, the value is calculated based on the given original dimension 3246cb05674SAndreas Gohr * 3256cb05674SAndreas Gohr * @param int|string $dim New Dimension 3266cb05674SAndreas Gohr * @param int $orig Original dimension 3276cb05674SAndreas Gohr * @return int 3286cb05674SAndreas Gohr */ 3296cb05674SAndreas Gohr protected function cleanDimension($dim, $orig) 3306cb05674SAndreas Gohr { 3316cb05674SAndreas Gohr if ($dim && substr($dim, -1) == '%') { 3326cb05674SAndreas Gohr $dim = round($orig * ((float)$dim / 100)); 3336cb05674SAndreas Gohr } else { 3346cb05674SAndreas Gohr $dim = (int)$dim; 3356cb05674SAndreas Gohr } 3366cb05674SAndreas Gohr 3376cb05674SAndreas Gohr return $dim; 3386cb05674SAndreas Gohr } 3396cb05674SAndreas Gohr 3406cb05674SAndreas Gohr /** 34192a8473aSAndreas Gohr * Calculates crop position 34292a8473aSAndreas Gohr * 34392a8473aSAndreas Gohr * Given the wanted final size, this calculates which exact area needs to be cut 34492a8473aSAndreas Gohr * from the original image to be then resized to the wanted dimensions. 34592a8473aSAndreas Gohr * 34692a8473aSAndreas Gohr * @param int $width 34792a8473aSAndreas Gohr * @param int $height 34892a8473aSAndreas Gohr * @return array (cropWidth, cropHeight, offsetX, offsetY) 34992a8473aSAndreas Gohr * @throws Exception 35092a8473aSAndreas Gohr */ 35192a8473aSAndreas Gohr protected function cropPosition($width, $height) 35292a8473aSAndreas Gohr { 35392a8473aSAndreas Gohr if ($width == 0 && $height == 0) { 35492a8473aSAndreas Gohr throw new Exception('You can not crop to 0x0'); 35592a8473aSAndreas Gohr } 35692a8473aSAndreas Gohr 35792a8473aSAndreas Gohr if (!$height) { 35892a8473aSAndreas Gohr $height = $width; 35992a8473aSAndreas Gohr } 36092a8473aSAndreas Gohr 36192a8473aSAndreas Gohr if (!$width) { 36292a8473aSAndreas Gohr $width = $height; 36392a8473aSAndreas Gohr } 36492a8473aSAndreas Gohr 36592a8473aSAndreas Gohr // calculate ratios 36692a8473aSAndreas Gohr $oldRatio = $this->width / $this->height; 36792a8473aSAndreas Gohr $newRatio = $width / $height; 36892a8473aSAndreas Gohr 36992a8473aSAndreas Gohr // calulate new size 37092a8473aSAndreas Gohr if ($newRatio >= 1) { 37192a8473aSAndreas Gohr if ($newRatio > $oldRatio) { 37292a8473aSAndreas Gohr $cropWidth = $this->width; 37392a8473aSAndreas Gohr $cropHeight = (int)($this->width / $newRatio); 37492a8473aSAndreas Gohr } else { 37592a8473aSAndreas Gohr $cropWidth = (int)($this->height * $newRatio); 37692a8473aSAndreas Gohr $cropHeight = $this->height; 37792a8473aSAndreas Gohr } 37892a8473aSAndreas Gohr } else { 37992a8473aSAndreas Gohr if ($newRatio < $oldRatio) { 38092a8473aSAndreas Gohr $cropWidth = (int)($this->height * $newRatio); 38192a8473aSAndreas Gohr $cropHeight = $this->height; 38292a8473aSAndreas Gohr } else { 38392a8473aSAndreas Gohr $cropWidth = $this->width; 38492a8473aSAndreas Gohr $cropHeight = (int)($this->width / $newRatio); 38592a8473aSAndreas Gohr } 38692a8473aSAndreas Gohr } 38792a8473aSAndreas Gohr 38892a8473aSAndreas Gohr // calculate crop offset 38992a8473aSAndreas Gohr $offsetX = (int)(($this->width - $cropWidth) / 2); 39092a8473aSAndreas Gohr $offsetY = (int)(($this->height - $cropHeight) / 2); 39192a8473aSAndreas Gohr 39292a8473aSAndreas Gohr return [$cropWidth, $cropHeight, $offsetX, $offsetY]; 39392a8473aSAndreas Gohr } 39492a8473aSAndreas Gohr 39592a8473aSAndreas Gohr /** 39692a8473aSAndreas Gohr * resize or crop images using PHP's libGD support 39792a8473aSAndreas Gohr * 39892a8473aSAndreas Gohr * @param int $toWidth desired width 39992a8473aSAndreas Gohr * @param int $toHeight desired height 40092a8473aSAndreas Gohr * @param int $offsetX offset of crop centre 40192a8473aSAndreas Gohr * @param int $offsetY offset of crop centre 40292a8473aSAndreas Gohr * @throws Exception 40392a8473aSAndreas Gohr */ 40492a8473aSAndreas Gohr protected function resizeOperation($toWidth, $toHeight, $offsetX = 0, $offsetY = 0) 40592a8473aSAndreas Gohr { 40692a8473aSAndreas Gohr $newimg = $this->createImage($toWidth, $toHeight); 40792a8473aSAndreas Gohr 40892a8473aSAndreas Gohr //try resampling first, fall back to resizing 40992a8473aSAndreas Gohr if ( 41092a8473aSAndreas Gohr !function_exists('imagecopyresampled') || 41192a8473aSAndreas Gohr !@imagecopyresampled( 41292a8473aSAndreas Gohr $newimg, 41392a8473aSAndreas Gohr $this->image, 41492a8473aSAndreas Gohr 0, 41592a8473aSAndreas Gohr 0, 41692a8473aSAndreas Gohr $offsetX, 41792a8473aSAndreas Gohr $offsetY, 41892a8473aSAndreas Gohr $toWidth, 41992a8473aSAndreas Gohr $toHeight, 42092a8473aSAndreas Gohr $this->width, 42192a8473aSAndreas Gohr $this->height 42292a8473aSAndreas Gohr ) 42392a8473aSAndreas Gohr ) { 42492a8473aSAndreas Gohr imagecopyresized( 42592a8473aSAndreas Gohr $newimg, 42692a8473aSAndreas Gohr $this->image, 42792a8473aSAndreas Gohr 0, 42892a8473aSAndreas Gohr 0, 42992a8473aSAndreas Gohr $offsetX, 43092a8473aSAndreas Gohr $offsetY, 43192a8473aSAndreas Gohr $toWidth, 43292a8473aSAndreas Gohr $toHeight, 43392a8473aSAndreas Gohr $this->width, 43492a8473aSAndreas Gohr $this->height 43592a8473aSAndreas Gohr ); 43692a8473aSAndreas Gohr } 43792a8473aSAndreas Gohr 43892a8473aSAndreas Gohr // destroy original GD image ressource and replace with new one 43992a8473aSAndreas Gohr imagedestroy($this->image); 44092a8473aSAndreas Gohr $this->image = $newimg; 44192a8473aSAndreas Gohr $this->width = $toWidth; 44292a8473aSAndreas Gohr $this->height = $toHeight; 44392a8473aSAndreas Gohr } 44492a8473aSAndreas Gohr 44592a8473aSAndreas Gohr} 446