I have found many questions about this on SO but none seem to solve my issue.
I need to resize images and save them to specific directories. My class below works exactly as I need it with the exception of transparent images. The transparent images turn black where they should be transparent.
Modified class of SimpleImage
<?php
/**
* Class ImageResize
*/
class ImageResize {
/**
* Image
* @var resource
*/
var $image;
/**
* Image type
* @var int
*/
var $image_type;
/**
* Loads the image file
* @param $filename
*/
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
unset($image_info);
if ($this->image_type == IMAGETYPE_JPEG) {
$this->image = imagecreatefromjpeg($filename);
} elseif ($this->image_type == IMAGETYPE_GIF) {
$this->image = imagecreatefromgif($filename);
} elseif ($this->image_type == IMAGETYPE_PNG) {
$this->image = imagecreatefrompng($filename);
}
}
/**
* Saves the image file
* @param $filename
* @param int $image_type
* @param int $compression
* @param null $permissions
*/
function save($filename, $image_type = IMAGETYPE_JPEG, $compression = 75, $permissions = NULL) {
if ($image_type == IMAGETYPE_JPEG) {
imagejpeg($this->image, $filename, $compression);
} elseif ($image_type == IMAGETYPE_GIF) {
imagegif($this->image, $filename);
} elseif ($image_type == IMAGETYPE_PNG) {
imagepng($this->image, $filename);
}
if ($permissions != NULL) {
chmod($filename, $permissions);
}
}
/**
* Outputs the image file
* @param int $image_type
*/
function output($image_type = IMAGETYPE_JPEG) {
if ($image_type == IMAGETYPE_JPEG) {
imagejpeg($this->image);
} elseif ($image_type == IMAGETYPE_GIF) {
imagegif($this->image);
} elseif ($image_type == IMAGETYPE_PNG) {
imagepng($this->image);
}
}
/**
* Gets the image width
* @return int
*/
function getWidth() {
return imagesx($this->image);
}
/**
* Gets the image height
* @return int
*/
function getHeight() {
return imagesy($this->image);
}
/**
* Resize the image to a specified height
* @param $height
*/
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width, $height);
unset($ratio, $width);
}
/**
* Resize the image to a specified width
* @param $width
*/
function resizeToWidth($width) {
$actualWidth = $this->getWidth();
if ($width < $actualWidth) {
$ratio = $width / $actualWidth;
$height = $this->getheight() * $ratio;
$this->resize($width, $height);
}
unset($actualWidth, $ratio, $height);
}
/**
* Scales the image
* @param $scale
*/
function scale($scale) {
$width = $this->getWidth() * $scale / 100;
$height = $this->getheight() * $scale / 100;
$this->resize($width, $height);
unset($width, $height);
}
/**
* Resize the image
* @param $width
* @param $height
*/
function resize($width, $height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
unset($new_image);
}
}
I have tried these fixes as I have found throughout SO and the all mighty Google:
Note: These fixes are added to the resize
method.
First Fix:
function resize($width, $height) {
$new_image = imagecreatetruecolor($width, $height);
// Attempt fix transparency
if ($this->image_type == IMAGETYPE_PNG || $this->image_type == IMAGETYPE_GIF) {
// Even tried with 255, 255, 255 for white and still no good
imagecolortransparent($new_image, imagecolorallocatealpha($new_image, 0, 0, 0, 127));
imagealphablending($new_image, false);
imagesavealpha($new_image, true);
}
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
unset($new_image);
}
The first fix does not change the black to white and it makes the image quality very low. So this doesn't seem to work properly.
Second Fix:
function resize($width, $height) {
$new_image = imagecreatetruecolor($width, $height);
if ($this->image_type == IMAGETYPE_PNG || $this->image_type == IMAGETYPE_GIF) {
$colourBlack = imagecolorallocate($new_image, 0, 0, 0);
imagecolortransparent($new_image, $colourBlack);
}
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
unset($new_image);
}
The second fix didn't seem to fix the black background either and the quality wasn't too bad but it could be better.
Third Fix:
function resize($width, $height) {
$new_image = imagecreatetruecolor($width, $height);
if ($this->image_type == IMAGETYPE_PNG || $this->image_type == IMAGETYPE_GIF) {
imagefill($new_image, 0, 0, imagecolorallocatealpha($new_image, 255, 255, 255, 127)); // Works but horrible quality
}
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
unset($new_image);
}
The third fix actually replaces the transparency with white but the quality is so bad I can't use it.
My Question:
I'm hoping I missed something but if not is there a way to do this? I am not wanting to use timThumb
, phpThumb
, or the class.upload.php
script. Mainly because of the system I am working with and the way timthumb
and phpthumb
works is not ideal. The class.upload.php
would be too much work to change all the scripts that use this... (old system that I got tossed on...)
Thanks for any help you can provide! :)
Edit:
I was finally able to get png transparency to work by doing this (answer found here):
function resize($width, $height) {
$new_image = imagecreatetruecolor($width, $height);
/* Check if this image is PNG or GIF, then set if Transparent*/
if(($this->image_type == IMAGETYPE_GIF) || ($this->image_type==IMAGETYPE_PNG)){
imagealphablending($new_image, false);
imagesavealpha($new_image,true);
$transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
}
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
unset($new_image);
}
I still need to figure out how to do this fix for gif