I'm using a modified version of the SimpleImage.php class: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
The edits I found on phpfreaks (http://www.phpfreaks.com/forums/index.php?topic=301811.0), but when I use, the png gets resized but the transparency is black.
I make the call like:
$max_width = 200; // set a max width
$max_height = 150; // set a max height
if($imgW > $imgH){ // width is greater
// resize to width up to max
if($imgW > $max_width) $image->resizeToWidth($max_width);
}
else { // height is greater
// resize to height up to max
if($imgH > $max_height) $image->resizeToHeight($max_height);
}
$image->save($_SERVER['DOCUMENT_ROOT']."/path/" . $new_filename);
I'm not sure what's missing. Any help is appreciated...
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
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);
}
}
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);
}
}
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 ) {
imageAlphaBlending($this->image, true);
imageSaveAlpha($this->image, true);
imagepng($this->image);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$height);
}
function resize($width,$height) {
// ADDED CODE IS HERE - NOT SURE WHY IT DOESN'T WORK FOR PNG
// Setup new image
$new_image = imagecreatetruecolor($width, $height);
// These parameters are required for handling PNG files.
imagealphablending($new_image, false);
imagesavealpha($new_image,true);
$transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
// Resize image
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
}
Now have the transparency working for PNG but not gif. Here are the edits to the specific functions in case it will help someone else:
Save Function:
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
// do this or they'll all go to jpeg
$image_type=$this->image_type;
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
// need this for transparent png to work
imagealphablending($this->image, false);
imagesavealpha($this->image,true);
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
Resize Function
function resize($width,$height,$forcesize='n') {
/* optional. if file is smaller, do not resize. */
if ($forcesize == 'n') {
if ($width > $this->getWidth() && $height > $this->getHeight()){
$width = $this->getWidth();
$height = $this->getHeight();
}
}
$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;
}
The function imagecreatetruecolor() does not work with GIF's. Use the imagecreate method instead:
if($this->image_type == IMAGETYPE_GIF){
$new_image = imagecreate( $Width, $Height ); // for gif files
} else{
$new_image = imagecreatetruecolor($Width, $Height); // for all other files
}
I haven't been playing with GD for a long time myself (I prefer Imagemagick), but you could try setting alpha also to the source image before copying:
...
// ADDED CODE IS HERE ..
imagealphablending($this->image, true);
...
HTH.
I did the same as in this https://stackoverflow.com/a/6401135/262462 but edited this part
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
// do this or they'll all go to jpeg
$image_type=$this->image_type;
to this
function save($filename, $image_type="original", $compression=75, $permissions=null) {
if ($image_type=="original")
$image_type=$this->image_type;
Related
I am resizing images using the code below, but their is problem with resizing png images with transparent background that it fills the background with black color.
Below is the full code of image resizing:
function store_uploaded_image($html_element_name, $new_img_width, $new_img_height ,$size ,$target_dir) {
$target_file = $target_dir .'image-'.$size.'.png';
$image = new SimpleImage();
$image->load($_FILES[$html_element_name]['tmp_name']);
$image->resize($new_img_width, $new_img_height);
$image->save($target_file);
return $target_file; //return name of saved file in case you want to store it in you database or show confirmation message to user
}
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
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);
}
}
function save($filename, $image_type=IMAGETYPE_PNG, $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);
}
}
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);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$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;
}
}
EDIT:
as #Marc B suggested, using imagealphablending and imagesavealpha before imagecopyresampled made it to work.
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );
I have a script which resizes images on server side before loading it to the client side.
Issue with this script is it compresses the file too, and that ends up in bad quality images.
Have a look at the script:
Image_Resize.php
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
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);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=0, $permissions=null) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,100);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
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);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$height);
}
function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
if ($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;
}
}
?>
Photo.php
<?php
require 'Image_Resize.php';
header('Content-Type: image/jpeg');
$imagenew=$_GET['id'];
$name=substr($imagenew,1);
if(file_exists($name)){
$image = new ResizeImage();
$image->load($imagenew);
$image->resize($_GET['width'], $_GET['height']); //25-width, 30-height
$image->output();
}
?>
I tried passing quality parameter to function imagejpeg in output function in Image_resize.php file. It's like this: imagejpeg($this->image,$filename,100);
But it's not working either(still outputs poor result than the original image). Anybody help?
Ok, here is the issue, the 400x400 jpeg looks fine the quality is great. However when resized to 300x300 it looks like it has been pulled apart and put back together by a 2 year old.
here is the script
$image->resize(300,300);
which calls the following script
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;
}
Here is the image class
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
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);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=99, $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);
}
}
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);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$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;
}
}
To test your function I had to implement the rest of the class. This works for me on PHP 5.5.14. Your code is included here unaltered:
class image
{
public $image = null;
public function __construct($img)
{
$this->image = imagecreatefromjpeg($img);
}
public 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;
}
public function getWidth()
{
return imagesx($this->image);
}
public function getHeight()
{
return imagesy($this->image);
}
}
$image = new image('img.jpg');
$image->resize(300,300);
header('Content-Type: image/jpeg');
imagejpeg($image->image);
exit;
This gives me the following output, which is a little blurry, but much better than your example.
Not really an answer but just helping out and I can't put pictures in comments...
In case you are wondering whether it is going to be worth installing and using ImageMagick, I have done it for you below:
convert in.jpg -resize 300x300 out.jpg
I have an images directory, some with massive resolutions, so I'd like to serve a much lower resolution version if they get hotlinked and I'm also overlaying a repeating image (like a watermark) informing the viewer that the image is stolen and where they can find the genuine original.
I've got the resampling working fine but when I add the function for the no hotlink image overlay, it doesn't work. The thing is, I know the watermarking script works too, on it's own, because I've used it elsewhere in another file on the site. Unfortunately I can't tell what the error is as the hotlink test sites don't output errors, they just show an empty image placeholder, and my host's log files are all like greek to me.
This is the script I have at the moment:
<?php
ini_set('memory_limit','250M');
$path = $_SERVER['DOCUMENT_ROOT'].$_SERVER['REQUEST_URI'];
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
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);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=60, $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);
}
}
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);
}
imagedestroy($image);
exit();
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$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;
}
function nothot() {
$hotlink = imagecreatefrompng('hotlink.png');
$hw = imagesx($hotlink);
$hh = imagesy($hotlink);
$img_paste_x = 0;
$img_paste_x = 0;
while($img_paste_x < $this->getWidth()){
$img_paste_y = 0;
while($img_paste_y < $this->getHeight()){
imagecopy($image, $hotlink, $img_paste_x, $img_paste_y, 0, 0, $hw, $hh);
$img_paste_y += $hh;
}
$img_paste_x += $hw;
}
imagedestroy($hotlink);
}
}
header('Content-Type: image/jpeg');
$image = new SimpleImage();
$image->load($path);
$image->resizeToWidth(600);
$image->nothot();
$image->output();
?>
Thanks for your help.
Change:
imagecopy($image, $hotlink, $img_paste_x, $img_paste_y, 0, 0, $hw, $hh);
to:
imagecopy($this->image, $hotlink, $img_paste_x, $img_paste_y, 0, 0, $hw, $hh);
Also not sure about the way you get the $path, some checks on whether the image exists wouldn't go a miss.
I use this class to upload images on my server. The problem is that when I upload transparent png images, the transparent parts get black. Is there a way to keep transparency in png images?
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
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);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=100, $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);
}
}
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);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$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;
}
}
I don't beleive that this class can handle transparent PNGs. The PHP documentation on imagecopyresampled explains this.
You'll probably need to extend the class to use imagecolorallocatealpha.
Read for reference: http://php.net/manual/en/function.imagecreatetruecolor.php
I used this one to ramain the transparency of a png or gif images.
imagecolortransparent($this->imageResized, imagecolorallocatealpha($this->imageResized, 0, 0, 0, 127));
imagealphablending($this->imageResized, false);
imagesavealpha($this->imageResized, true);
You may need to use
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
before imagepng
Solution can be found here:
PNG Transparency Resize with SimpleImage.php Class
it modifies a bit the class in order to allow transparencies in case of PNG and GIF images.