diff --git a/lib/ImageResize.php b/lib/ImageResize.php index 1410b72..3c187ba 100644 --- a/lib/ImageResize.php +++ b/lib/ImageResize.php @@ -16,8 +16,9 @@ class ImageResize const CROPTOPCENTER = 6; public $quality_jpg = 85; + public $quality_webp = 85; public $quality_png = 6; - public $quality_truecolor = TRUE; + public $quality_truecolor = true; public $interlace = 1; @@ -39,7 +40,7 @@ class ImageResize protected $source_w; protected $source_h; - + protected $source_info; /** @@ -51,9 +52,9 @@ class ImageResize */ public static function createFromString($image_data) { - if(empty($image_data) || $image_data === null) { - throw new ImageResizeException('image_data must not be empty'); - } + if (empty($image_data) || $image_data === null) { + throw new ImageResizeException('image_data must not be empty'); + } $resize = new self('data://application/octet-stream;base64,' . base64_encode($image_data)); return $resize; } @@ -67,16 +68,18 @@ public static function createFromString($image_data) */ public function __construct($filename) { + if (!defined('IMAGETYPE_WEBP')) { + define('IMAGETYPE_WEBP', 18); + } + if ($filename === null || empty($filename) || (substr($filename, 0, 7) !== 'data://' && !is_file($filename))) { + throw new ImageResizeException('File does not exist'); + } + + $finfo = finfo_open(FILEINFO_MIME_TYPE); + if (strstr(finfo_file($finfo, $filename), 'image') === false) { + throw new ImageResizeException('Unsupported file type'); + } - if($filename === null || empty($filename) || (substr($filename,0,7) !== 'data://' && !is_file($filename))) { - throw new ImageResizeException('File does not exist'); - } - - $finfo = finfo_open(FILEINFO_MIME_TYPE); - if(strstr(finfo_file($finfo, $filename),'image') === false) { - throw new ImageResizeException('Unsupported file type'); - } - if (!$image_info = getimagesize($filename, $this->source_info)) { $image_info = getimagesize($filename); } @@ -85,33 +88,40 @@ public function __construct($filename) throw new ImageResizeException('Could not read file'); } - list ( + list( $this->original_w, $this->original_h, $this->source_type ) = $image_info; switch ($this->source_type) { - case IMAGETYPE_GIF: - $this->source_image = imagecreatefromgif($filename); - break; + case IMAGETYPE_GIF: + $this->source_image = imagecreatefromgif($filename); + break; - case IMAGETYPE_JPEG: - $this->source_image = $this->imageCreateJpegfromExif($filename); + case IMAGETYPE_JPEG: + $this->source_image = $this->imageCreateJpegfromExif($filename); - // set new width and height for image, maybe it has changed - $this->original_w = ImageSX($this->source_image); - $this->original_h = ImageSY($this->source_image); + // set new width and height for image, maybe it has changed + $this->original_w = ImageSX($this->source_image); + $this->original_h = ImageSY($this->source_image); - break; + break; - case IMAGETYPE_PNG: - $this->source_image = imagecreatefrompng($filename); - break; + case IMAGETYPE_PNG: + $this->source_image = imagecreatefrompng($filename); + break; - default: - throw new ImageResizeException('Unsupported image type'); - break; + case IMAGETYPE_WEBP: + if (version_compare(PHP_VERSION, '5.5.0', '<')) { + throw new ImageResizeException('For WebP support PHP >= 5.5.0 is required'); + } + $this->source_image = imagecreatefromwebp($filename); + break; + + default: + throw new ImageResizeException('Unsupported image type'); + break; } if (!$this->source_image) { @@ -122,34 +132,35 @@ public function __construct($filename) } // http://stackoverflow.com/a/28819866 - public function imageCreateJpegfromExif($filename){ - $img = imagecreatefromjpeg($filename); - - if (!function_exists('exif_read_data') || !isset($this->source_info['APP1']) || strpos ($this->source_info['APP1'], 'Exif') !== 0) { - return $img; - } - - $exif = exif_read_data($filename); - - if (!$exif || !isset($exif['Orientation'])){ - return $img; - } + public function imageCreateJpegfromExif($filename) + { + $img = imagecreatefromjpeg($filename); - $orientation = $exif['Orientation']; + if (!function_exists('exif_read_data') || !isset($this->source_info['APP1']) || strpos($this->source_info['APP1'], 'Exif') !== 0) { + return $img; + } + + $exif = exif_read_data($filename); - if ($orientation === 6 || $orientation === 5){ - $img = imagerotate($img, 270, null); - } else if ($orientation === 3 || $orientation === 4){ - $img = imagerotate($img, 180, null); - } else if ($orientation === 8 || $orientation === 7){ - $img = imagerotate($img, 90, null); - } + if (!$exif || !isset($exif['Orientation'])) { + return $img; + } - if ($orientation === 5 || $orientation === 4 || $orientation === 7){ - imageflip($img, IMG_FLIP_HORIZONTAL); - } + $orientation = $exif['Orientation']; - return $img; + if ($orientation === 6 || $orientation === 5) { + $img = imagerotate($img, 270, null); + } elseif ($orientation === 3 || $orientation === 4) { + $img = imagerotate($img, 180, null); + } elseif ($orientation === 8 || $orientation === 7) { + $img = imagerotate($img, 90, null); + } + + if ($orientation === 5 || $orientation === 4 || $orientation === 7) { + imageflip($img, IMG_FLIP_HORIZONTAL); + } + + return $img; } /** @@ -167,36 +178,46 @@ public function save($filename, $image_type = null, $quality = null, $permission $quality = is_numeric($quality) ? (int) abs($quality) : null; switch ($image_type) { - case IMAGETYPE_GIF: - $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + case IMAGETYPE_GIF: + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); - $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1); - imagecolortransparent($dest_image, $background); - imagefill($dest_image, 0, 0 , $background); - imagesavealpha($dest_image, true); - break; + $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1); + imagecolortransparent($dest_image, $background); + imagefill($dest_image, 0, 0, $background); + imagesavealpha($dest_image, true); + break; - case IMAGETYPE_JPEG: - $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + case IMAGETYPE_JPEG: + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); - $background = imagecolorallocate($dest_image, 255, 255, 255); - imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background); - break; + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background); + break; - case IMAGETYPE_PNG: - if (!$this->quality_truecolor && !imageistruecolor($this->source_image)) { - $dest_image = imagecreate($this->getDestWidth(), $this->getDestHeight()); + case IMAGETYPE_WEBP: + if (version_compare(PHP_VERSION, '5.5.0', '<')) { + throw new ImageResizeException('For WebP support PHP >= 5.5.0 is required'); + } + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background); + break; - $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1); - imagecolortransparent($dest_image, $background); - imagefill($dest_image, 0, 0 , $background); - } else { - $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); - } + case IMAGETYPE_PNG: + if (!$this->quality_truecolor && !imageistruecolor($this->source_image)) { + $dest_image = imagecreate($this->getDestWidth(), $this->getDestHeight()); - imagealphablending($dest_image, false); - imagesavealpha($dest_image, true); - break; + $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1); + imagecolortransparent($dest_image, $background); + imagefill($dest_image, 0, 0, $background); + } else { + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + } + + imagealphablending($dest_image, false); + imagesavealpha($dest_image, true); + break; } imageinterlace($dest_image, $this->interlace); @@ -215,25 +236,36 @@ public function save($filename, $image_type = null, $quality = null, $permission ); switch ($image_type) { - case IMAGETYPE_GIF: - imagegif($dest_image, $filename); - break; + case IMAGETYPE_GIF: + imagegif($dest_image, $filename); + break; + + case IMAGETYPE_JPEG: + if ($quality === null || $quality > 100) { + $quality = $this->quality_jpg; + } - case IMAGETYPE_JPEG: - if ($quality === null || $quality > 100) { - $quality = $this->quality_jpg; - } + imagejpeg($dest_image, $filename, $quality); + break; - imagejpeg($dest_image, $filename, $quality); - break; + case IMAGETYPE_WEBP: + if (version_compare(PHP_VERSION, '5.5.0', '<')) { + throw new ImageResizeException('For WebP support PHP >= 5.5.0 is required'); + } + if ($quality === null) { + $quality = $this->quality_webp; + } + + imagewebp($dest_image, $filename, $quality); + break; - case IMAGETYPE_PNG: - if ($quality === null || $quality > 9) { - $quality = $this->quality_png; - } + case IMAGETYPE_PNG: + if ($quality === null || $quality > 9) { + $quality = $this->quality_png; + } - imagepng($dest_image, $filename, $quality); - break; + imagepng($dest_image, $filename, $quality); + break; } if ($permissions) { @@ -256,7 +288,7 @@ public function getImageAsString($image_type = null, $quality = null) { $string_temp = tempnam(sys_get_temp_dir(), ''); - $this->save($string_temp , $image_type, $quality); + $this->save($string_temp, $image_type, $quality); $string = file_get_contents($string_temp); @@ -266,10 +298,10 @@ public function getImageAsString($image_type = null, $quality = null) } /** - * Convert the image to string with the current settings - * - * @return string - */ + * Convert the image to string with the current settings + * + * @return string + */ public function __toString() { return $this->getImageAsString(); @@ -309,7 +341,7 @@ public function resizeToShortSide($max_short, $allow_enlarge = false) $this->resize($max_short, $long, $allow_enlarge); } - + return $this; } @@ -333,7 +365,7 @@ public function resizeToLongSide($max_long, $allow_enlarge = false) $this->resize($max_long, $short, $allow_enlarge); } - + return $this; } @@ -381,7 +413,7 @@ public function resizeToWidth($width, $allow_enlarge = false) */ public function resizeToBestFit($max_width, $max_height, $allow_enlarge = false) { - if($this->getSourceWidth() <= $max_width && $this->getSourceHeight() <= $max_height && $allow_enlarge === false){ + if ($this->getSourceWidth() <= $max_width && $this->getSourceHeight() <= $max_height && $allow_enlarge === false) { return $this; } @@ -389,7 +421,7 @@ public function resizeToBestFit($max_width, $max_height, $allow_enlarge = false) $width = $max_width; $height = $width * $ratio; - if($height > $max_height){ + if ($height > $max_height) { $height = $max_height; $width = $height / $ratio; } @@ -508,21 +540,21 @@ public function crop($width, $height, $allow_enlarge = false, $position = self:: */ public function freecrop($width, $height, $x = false, $y = false) { - if($x === false or $y === false){ - return $this->crop($width, $height); + if ($x === false or $y === false) { + return $this->crop($width, $height); } $this->source_x = $x; $this->source_y = $y; - if($width > $this->getSourceWidth() - $x){ - $this->source_w = $this->getSourceWidth() - $x; + if ($width > $this->getSourceWidth() - $x) { + $this->source_w = $this->getSourceWidth() - $x; } else { - $this->source_w = $width; + $this->source_w = $width; } - if($height > $this->getSourceHeight() - $y){ - $this->source_h = $this->getSourceHeight() - $y; + if ($height > $this->getSourceHeight() - $y) { + $this->source_h = $this->getSourceHeight() - $y; } else { - $this->source_h = $height; + $this->source_h = $height; } $this->dest_w = $width; @@ -581,17 +613,17 @@ protected function getCropPosition($expectedSize, $position = self::CROPCENTER) { $size = 0; switch ($position) { - case self::CROPBOTTOM: - case self::CROPRIGHT: - $size = $expectedSize; - break; - case self::CROPCENTER: - case self::CROPCENTRE: - $size = $expectedSize / 2; - break; - case self::CROPTOPCENTER: - $size = $expectedSize / 4; - break; + case self::CROPBOTTOM: + case self::CROPRIGHT: + $size = $expectedSize; + break; + case self::CROPCENTER: + case self::CROPCENTRE: + $size = $expectedSize / 2; + break; + case self::CROPTOPCENTER: + $size = $expectedSize / 4; + break; } return $size; } @@ -599,52 +631,55 @@ protected function getCropPosition($expectedSize, $position = self::CROPCENTER) // imageflip definition for PHP < 5.5 if (!function_exists('imageflip')) { - define('IMG_FLIP_HORIZONTAL', 0); - define('IMG_FLIP_VERTICAL', 1); - define('IMG_FLIP_BOTH', 2); - - function imageflip($image, $mode) { - switch ($mode) { - case IMG_FLIP_HORIZONTAL: { - $max_x = imagesx($image) - 1; - $half_x = $max_x / 2; - $sy = imagesy($image); - $temp_image = imageistruecolor($image)? imagecreatetruecolor(1, $sy): imagecreate(1, $sy); - for ($x = 0; $x < $half_x; ++$x) { - imagecopy($temp_image, $image, 0, 0, $x, 0, 1, $sy); - imagecopy($image, $image, $x, 0, $max_x - $x, 0, 1, $sy); - imagecopy($image, $temp_image, $max_x - $x, 0, 0, 0, 1, $sy); + define('IMG_FLIP_HORIZONTAL', 0); + define('IMG_FLIP_VERTICAL', 1); + define('IMG_FLIP_BOTH', 2); + + function imageflip($image, $mode) + { + switch ($mode) { + case IMG_FLIP_HORIZONTAL: { + $max_x = imagesx($image) - 1; + $half_x = $max_x / 2; + $sy = imagesy($image); + $temp_image = imageistruecolor($image)? imagecreatetruecolor(1, $sy): imagecreate(1, $sy); + for ($x = 0; $x < $half_x; ++$x) { + imagecopy($temp_image, $image, 0, 0, $x, 0, 1, $sy); + imagecopy($image, $image, $x, 0, $max_x - $x, 0, 1, $sy); + imagecopy($image, $temp_image, $max_x - $x, 0, 0, 0, 1, $sy); + } + break; } - break; - } - case IMG_FLIP_VERTICAL: { - $sx = imagesx($image); - $max_y = imagesy($image) - 1; - $half_y = $max_y / 2; - $temp_image = imageistruecolor($image)? imagecreatetruecolor($sx, 1): imagecreate($sx, 1); - for ($y = 0; $y < $half_y; ++$y) { - imagecopy($temp_image, $image, 0, 0, 0, $y, $sx, 1); - imagecopy($image, $image, 0, $y, 0, $max_y - $y, $sx, 1); - imagecopy($image, $temp_image, 0, $max_y - $y, 0, 0, $sx, 1); +case IMG_FLIP_VERTICAL: { + $sx = imagesx($image); + $max_y = imagesy($image) - 1; + $half_y = $max_y / 2; + $temp_image = imageistruecolor($image)? imagecreatetruecolor($sx, 1): imagecreate($sx, 1); + for ($y = 0; $y < $half_y; ++$y) { + imagecopy($temp_image, $image, 0, 0, 0, $y, $sx, 1); + imagecopy($image, $image, 0, $y, 0, $max_y - $y, $sx, 1); + imagecopy($image, $temp_image, 0, $max_y - $y, 0, 0, $sx, 1); + } + break; +} +case IMG_FLIP_BOTH: { + $sx = imagesx($image); + $sy = imagesy($image); + $temp_image = imagerotate($image, 180, 0); + imagecopy($image, $temp_image, 0, 0, 0, 0, $sx, $sy); + break; +} +default: { + return; +} } - break; - } - case IMG_FLIP_BOTH: { - $sx = imagesx($image); - $sy = imagesy($image); - $temp_image = imagerotate($image, 180, 0); - imagecopy($image, $temp_image, 0, 0, 0, 0, $sx, $sy); - break; - } - default: { - return; - } + imagedestroy($temp_image); } - imagedestroy($temp_image); - } } /** * PHP Exception used in the ImageResize class */ -class ImageResizeException extends \Exception {} +class ImageResizeException extends \Exception +{ +}