Update Simple Image Class from 3.6.3 to 3.7.0
This commit is contained in:
parent
55d3b162bf
commit
ce685e5f86
1 changed files with 97 additions and 58 deletions
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
//
|
||||||
// SimpleImage v3.6.3
|
// SimpleImage
|
||||||
//
|
//
|
||||||
// A PHP class that makes working with images as simple as possible.
|
// A PHP class that makes working with images as simple as possible.
|
||||||
//
|
//
|
||||||
|
@ -31,7 +31,8 @@ class SimpleImage {
|
||||||
ERR_LIB_NOT_LOADED = 8,
|
ERR_LIB_NOT_LOADED = 8,
|
||||||
ERR_UNSUPPORTED_FORMAT = 9,
|
ERR_UNSUPPORTED_FORMAT = 9,
|
||||||
ERR_WEBP_NOT_ENABLED = 10,
|
ERR_WEBP_NOT_ENABLED = 10,
|
||||||
ERR_WRITE = 11;
|
ERR_WRITE = 11,
|
||||||
|
ERR_INVALID_FLAG = 12;
|
||||||
|
|
||||||
|
|
||||||
protected $image;
|
protected $image;
|
||||||
|
@ -46,9 +47,10 @@ class SimpleImage {
|
||||||
* Creates a new SimpleImage object.
|
* Creates a new SimpleImage object.
|
||||||
*
|
*
|
||||||
* @param string $image An image file or a data URI to load.
|
* @param string $image An image file or a data URI to load.
|
||||||
|
* @param array $flags Optional override of default flags.
|
||||||
* @throws \Exception Thrown if the GD library is not found; file|URI or image data is invalid.
|
* @throws \Exception Thrown if the GD library is not found; file|URI or image data is invalid.
|
||||||
*/
|
*/
|
||||||
public function __construct($image = null) {
|
public function __construct($image = '', $flags = []) {
|
||||||
// Check for the required GD extension
|
// Check for the required GD extension
|
||||||
if(extension_loaded('gd')) {
|
if(extension_loaded('gd')) {
|
||||||
// Ignore JPEG warnings that cause imagecreatefromjpeg() to fail
|
// Ignore JPEG warnings that cause imagecreatefromjpeg() to fail
|
||||||
|
@ -57,6 +59,16 @@ class SimpleImage {
|
||||||
throw new \Exception('Required extension GD is not loaded.', self::ERR_GD_NOT_ENABLED);
|
throw new \Exception('Required extension GD is not loaded.', self::ERR_GD_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Associative array of flags.
|
||||||
|
$this->flags = [
|
||||||
|
"sslVerify" => true // Skip SSL peer validation
|
||||||
|
];
|
||||||
|
|
||||||
|
// Override default flag values.
|
||||||
|
foreach($flags as $flag => $value) {
|
||||||
|
$this->setFlag($flag, $value);
|
||||||
|
}
|
||||||
|
|
||||||
// Load an image through the constructor
|
// Load an image through the constructor
|
||||||
if(preg_match('/^data:(.*?);/', $image)) {
|
if(preg_match('/^data:(.*?);/', $image)) {
|
||||||
$this->fromDataUri($image);
|
$this->fromDataUri($image);
|
||||||
|
@ -77,6 +89,37 @@ class SimpleImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper functions
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set flag value.
|
||||||
|
*
|
||||||
|
* @param string $flag Name of the flag to set.
|
||||||
|
* @param boolean $value State of the flag.
|
||||||
|
* @throws \Exception Thrown if flag does not exist (no default value).
|
||||||
|
*/
|
||||||
|
public function setFlag($flag, $value) {
|
||||||
|
// Throw if flag does not exist
|
||||||
|
if(!in_array($flag, array_keys($this->flags))) {
|
||||||
|
throw new \Exception('Invalid flag.', self::ERR_INVALID_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set flag value by name
|
||||||
|
$this->flags[$flag] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get flag value.
|
||||||
|
*
|
||||||
|
* @param string $flag Name of the flag to get.
|
||||||
|
* @return boolean|null
|
||||||
|
*/
|
||||||
|
public function getFlag($flag) {
|
||||||
|
return in_array($flag, array_keys($this->flags)) ? $this->flags[$flag] : null;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Loaders
|
// Loaders
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -118,70 +161,66 @@ class SimpleImage {
|
||||||
* Loads an image from a file.
|
* Loads an image from a file.
|
||||||
*
|
*
|
||||||
* @param string $file The image file to load.
|
* @param string $file The image file to load.
|
||||||
|
* @param boolean $sslVerify Set to false to skip SSL validation.
|
||||||
* @throws \Exception Thrown if file or image data is invalid.
|
* @throws \Exception Thrown if file or image data is invalid.
|
||||||
* @return \claviska\SimpleImage
|
* @return \claviska\SimpleImage
|
||||||
*/
|
*/
|
||||||
public function fromFile($file) {
|
public function fromFile($file) {
|
||||||
// Check if the file exists and is readable. We're using fopen() instead of file_exists()
|
// Set fopen options.
|
||||||
// because not all URL wrappers support the latter.
|
$sslVerify = $this->getFlag("sslVerify"); // Don't perform peer validation when true
|
||||||
$handle = @fopen($file, 'r');
|
$opts = [
|
||||||
if($handle === false) {
|
"ssl" => [
|
||||||
|
"verify_peer" => $sslVerify,
|
||||||
|
"verify_peer_name" => $sslVerify
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Check if the file exists and is readable.
|
||||||
|
$file = @file_get_contents($file, false, stream_context_create($opts));
|
||||||
|
if($file === false) {
|
||||||
throw new \Exception("File not found: $file", self::ERR_FILE_NOT_FOUND);
|
throw new \Exception("File not found: $file", self::ERR_FILE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
fclose($handle);
|
|
||||||
|
// Create image object from string
|
||||||
|
$this->image = imagecreatefromstring($file);
|
||||||
|
|
||||||
// Get image info
|
// Get image info
|
||||||
$info = @getimagesize($file);
|
$info = @getimagesizefromstring($file);
|
||||||
if($info === false) {
|
if($info === false) {
|
||||||
throw new \Exception("Invalid image file: $file", self::ERR_INVALID_IMAGE);
|
throw new \Exception("Invalid image file: $file", self::ERR_INVALID_IMAGE);
|
||||||
}
|
}
|
||||||
$this->mimeType = $info['mime'];
|
$this->mimeType = $info['mime'];
|
||||||
|
|
||||||
// Create image object from file
|
|
||||||
switch($this->mimeType) {
|
|
||||||
case 'image/gif':
|
|
||||||
// Load the gif
|
|
||||||
$gif = imagecreatefromgif($file);
|
|
||||||
if($gif) {
|
|
||||||
// Copy the gif over to a true color image to preserve its transparency. This is a
|
|
||||||
// workaround to prevent imagepalettetruecolor() from borking transparency.
|
|
||||||
$width = imagesx($gif);
|
|
||||||
$height = imagesy($gif);
|
|
||||||
$this->image = imagecreatetruecolor($width, $height);
|
|
||||||
$transparentColor = imagecolorallocatealpha($this->image, 0, 0, 0, 127);
|
|
||||||
imagecolortransparent($this->image, $transparentColor);
|
|
||||||
imagefill($this->image, 0, 0, $transparentColor);
|
|
||||||
imagecopy($this->image, $gif, 0, 0, 0, 0, $width, $height);
|
|
||||||
imagedestroy($gif);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'image/jpeg':
|
|
||||||
$this->image = imagecreatefromjpeg($file);
|
|
||||||
break;
|
|
||||||
case 'image/png':
|
|
||||||
$this->image = imagecreatefrompng($file);
|
|
||||||
break;
|
|
||||||
case 'image/webp':
|
|
||||||
$this->image = imagecreatefromwebp($file);
|
|
||||||
break;
|
|
||||||
case 'image/bmp':
|
|
||||||
case 'image/x-ms-bmp':
|
|
||||||
case 'image/x-windows-bmp':
|
|
||||||
$this->image = imagecreatefrombmp($file);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!$this->image) {
|
if(!$this->image) {
|
||||||
throw new \Exception("Unsupported format: " . $this->mimeType, self::ERR_UNSUPPORTED_FORMAT);
|
throw new \Exception("Unsupported format: " . $this->mimeType, self::ERR_UNSUPPORTED_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch($this->mimeType) {
|
||||||
|
case 'image/gif':
|
||||||
|
// Copy the gif over to a true color image to preserve its transparency. This is a
|
||||||
|
// workaround to prevent imagepalettetotruecolor() from borking transparency.
|
||||||
|
$width = imagesx($this->image);
|
||||||
|
$height = imagesx($this->image);
|
||||||
|
|
||||||
|
$gif = imagecreatetruecolor((int) $width, (int) $height);
|
||||||
|
$alpha = imagecolorallocatealpha($gif, 0, 0, 0, 127);
|
||||||
|
imagecolortransparent($gif, $alpha);
|
||||||
|
imagefill($gif, 0, 0, $alpha);
|
||||||
|
|
||||||
|
imagecopy($this->image, $gif, 0, 0, 0, 0, $width, $height);
|
||||||
|
imagedestroy($gif);
|
||||||
|
break;
|
||||||
|
case 'image/jpeg':
|
||||||
|
// Load exif data from JPEG images
|
||||||
|
if(function_exists('exif_read_data')) {
|
||||||
|
$this->exif = @exif_read_data("data://image/jpeg;base64," . base64_encode($file));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert pallete images to true color images
|
// Convert pallete images to true color images
|
||||||
imagepalettetotruecolor($this->image);
|
imagepalettetotruecolor($this->image);
|
||||||
|
|
||||||
// Load exif data from JPEG images
|
|
||||||
if($this->mimeType === 'image/jpeg' && function_exists('exif_read_data')) {
|
|
||||||
$this->exif = @exif_read_data($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +233,7 @@ class SimpleImage {
|
||||||
* @return \claviska\SimpleImage
|
* @return \claviska\SimpleImage
|
||||||
*/
|
*/
|
||||||
public function fromNew($width, $height, $color = 'transparent') {
|
public function fromNew($width, $height, $color = 'transparent') {
|
||||||
$this->image = imagecreatetruecolor($width, $height);
|
$this->image = imagecreatetruecolor((int) $width, (int) $height);
|
||||||
|
|
||||||
// Use PNG for dynamically created images because it's lossless and supports transparency
|
// Use PNG for dynamically created images because it's lossless and supports transparency
|
||||||
$this->mimeType = 'image/png';
|
$this->mimeType = 'image/png';
|
||||||
|
@ -490,7 +529,7 @@ class SimpleImage {
|
||||||
imagefilter($srcIm, IMG_FILTER_COLORIZE, 0, 0, 0, 127 * ((100 - $pct) / 100));
|
imagefilter($srcIm, IMG_FILTER_COLORIZE, 0, 0, 0, 127 * ((100 - $pct) / 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
imagecopy($dstIm, $srcIm, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH);
|
imagecopy($dstIm, $srcIm, (int) $dstX, (int) $dstY, (int) $srcX, (int) $srcY, (int) $srcW, (int) $srcH);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -593,7 +632,7 @@ class SimpleImage {
|
||||||
// Avoid using native imagecrop() because of a bug with PNG transparency
|
// Avoid using native imagecrop() because of a bug with PNG transparency
|
||||||
$dstW = abs($x2 - $x1);
|
$dstW = abs($x2 - $x1);
|
||||||
$dstH = abs($y2 - $y1);
|
$dstH = abs($y2 - $y1);
|
||||||
$newImage = imagecreatetruecolor($dstW, $dstH);
|
$newImage = imagecreatetruecolor((int) $dstW, (int) $dstH);
|
||||||
$transparentColor = imagecolorallocatealpha($newImage, 0, 0, 0, 127);
|
$transparentColor = imagecolorallocatealpha($newImage, 0, 0, 0, 127);
|
||||||
imagecolortransparent($newImage, $transparentColor);
|
imagecolortransparent($newImage, $transparentColor);
|
||||||
imagefill($newImage, 0, 0, $transparentColor);
|
imagefill($newImage, 0, 0, $transparentColor);
|
||||||
|
@ -603,10 +642,10 @@ class SimpleImage {
|
||||||
$newImage,
|
$newImage,
|
||||||
$this->image,
|
$this->image,
|
||||||
0, 0, min($x1, $x2), min($y1, $y2),
|
0, 0, min($x1, $x2), min($y1, $y2),
|
||||||
$dstW,
|
(int) $dstW,
|
||||||
$dstH,
|
(int) $dstH,
|
||||||
$dstW,
|
(int) $dstW,
|
||||||
$dstH
|
(int) $dstH
|
||||||
);
|
);
|
||||||
|
|
||||||
// Swap out the new image
|
// Swap out the new image
|
||||||
|
@ -802,7 +841,7 @@ class SimpleImage {
|
||||||
// We can't use imagescale because it doesn't seem to preserve transparency properly. The
|
// We can't use imagescale because it doesn't seem to preserve transparency properly. The
|
||||||
// workaround is to create a new truecolor image, allocate a transparent color, and copy the
|
// workaround is to create a new truecolor image, allocate a transparent color, and copy the
|
||||||
// image over to it using imagecopyresampled.
|
// image over to it using imagecopyresampled.
|
||||||
$newImage = imagecreatetruecolor($width, $height);
|
$newImage = imagecreatetruecolor((int) $width, (int) $height);
|
||||||
$transparentColor = imagecolorallocatealpha($newImage, 0, 0, 0, 127);
|
$transparentColor = imagecolorallocatealpha($newImage, 0, 0, 0, 127);
|
||||||
imagecolortransparent($newImage, $transparentColor);
|
imagecolortransparent($newImage, $transparentColor);
|
||||||
imagefill($newImage, 0, 0, $transparentColor);
|
imagefill($newImage, 0, 0, $transparentColor);
|
||||||
|
@ -810,8 +849,8 @@ class SimpleImage {
|
||||||
$newImage,
|
$newImage,
|
||||||
$this->image,
|
$this->image,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
$width,
|
(int) $width,
|
||||||
$height,
|
(int) $height,
|
||||||
$this->getWidth(),
|
$this->getWidth(),
|
||||||
$this->getHeight()
|
$this->getHeight()
|
||||||
);
|
);
|
||||||
|
@ -1885,7 +1924,7 @@ class SimpleImage {
|
||||||
$color['red'],
|
$color['red'],
|
||||||
$color['green'],
|
$color['green'],
|
||||||
$color['blue'],
|
$color['blue'],
|
||||||
127 - ($color['alpha'] * 127)
|
(int) (127 - ($color['alpha'] * 127))
|
||||||
);
|
);
|
||||||
if($index > -1) {
|
if($index > -1) {
|
||||||
// Yes, return this color index
|
// Yes, return this color index
|
||||||
|
|
Loading…
Add table
Reference in a new issue