I have a problem in my images using the GD library in my live site.
Is there an issue of GD library in linux? I implemented the resizing and cropping of image using the GD library, but somehow only the resizing works. Also, png images have black background after resized. My codes are working totally fine in local but not in my hosted site. I didn't get any errors so I am not sure where the problem is.
This is my code:
$info = getimagesize($src);
$source_image = '';
if ($info['mime'] == 'image/jpeg')
$source_image = imagecreatefromjpeg($src);
elseif ($info['mime'] == 'image/gif')
$source_image = imagecreatefromgif($src);
elseif ($info['mime'] == 'image/png')
$source_image = imagecreatefrompng($src);
$cropped = imagecropauto($source_image, IMG_CROP_DEFAULT);
if ($cropped !== false) {
imagedestroy($source_image);
$source_image = $cropped;
}
$width = imagesx($source_image);
$height = imagesy($source_image);
$maxHeight = floor($height * ($maxWidth / $width));
$dst = imagecreatetruecolor($maxWidth, $maxHeight);
$background = imagecolorallocate($dst, 0, 0, 0);
imagecolortransparent($dst, $background);
imagealphablending($dst, false);
imagesavealpha($dst,true);
imagecopyresampled($dst, $source_image, 0, 0, 0, 0, $maxWidth, $maxHeight, $width, $height);
if ($info['mime'] == 'image/jpeg')
imagejpeg($dst, $newFilename);
elseif ($info['mime'] == 'image/gif')
imagegif($dst, $newFilename);
elseif ($info['mime'] == 'image/png')
imagepng($dst, $newFilename);
Please help. Thank You
Replace IMG_CROP_DEFAULT with IMG_CROP_SIDES
also read documentation click here you also fill color using
<?php
// Create a 300x300px transparant image with a 100px wide red circle in the middle
$i = imagecreatetruecolor(300, 300);
imagealphablending($i, FALSE);
imagesavealpha($i, TRUE);
$transparant = imagecolorallocatealpha($i, 0xDD, 0xDD, 0xDD, 0x7F);
imagecolortransparent($i, $transparant); // Set background transparent
imagefill($i, 0, 0, $transparant);
$red = imagecolorallocate($i, 0xFF, 0x0, 0x0);
imagefilledellipse($i, 150, 150, 100, 100, $red);
imagepng($i, "red_300.png");
// Crop away transparant parts and save
$i2 = imagecropauto($i, IMG_CROP_DEFAULT); //Attempts to use IMG_CROP_TRANSPARENT and if it fails it falls back to IMG_CROP_SIDES.
imagepng($i2, "red_crop_trans.png");
imagedestroy($i2);
// Crop away bg-color parts and save
$i2 = imagecropauto($i, IMG_CROP_SIDES);
imagepng($i2, "red_crop_sides.png");
imagedestroy($i2);
// clean up org image
imagedestroy($i);
?>
Related
I have the task to develop a plugin for WordPress that adds watermark to uploaded images using PHP. WP hosted on AWS Bitnami. They all need to be exactly 800x800px so I upscale/downscale the source image and then add the PNG watermark.
For some reason, most of the time images end up with terrible grey artifacts on them. 5% of the time they are perfectly okay, I could not see any patterns that lead to success.
This is what happens:
Image with failed watermark
Image with good watermark
This is my code:
function add_watermark($resized_image) {
ini_set('memory_limit', '256M');
$watermark = imagecreatefrompng( '/transparency-award-watermark.png' );
imagealphablending($watermark, false); // Saw that on StackOverflow, didn't help
imagesavealpha($watermark, true); // That one too
$info = getimagesize($resized_image);
if(max($info[0], $info[1]) != 800) {
resize_image($resized_image);
}
if( $info[2] == IMG_JPG or $info[2] == IMG_JPEG ) $image = imagecreatefromjpeg($resized_image);
if( $info[2] == IMG_PNG ) $image = imagecreatefrompng($resized_image);
$sx = imagesx($watermark);
$sy = imagesy($watermark);
imagecopy($image, $watermark, imagesx($image) - $sx, imagesy($image) - $sy, 0, 0, imagesx($watermark), imagesy($watermark));
imagejpeg($image, $resized_image, 95);
imagedestroy($image);
imagedestroy($watermark);
}
function resize_image($orig_image) {
$info = getimagesize($orig_image);
if( $info[2] == IMG_JPG or $info[2] == IMG_JPEG ) $source_image = imagecreatefromjpeg($orig_image);
if( $info[2] == IMG_PNG ) $source_image = imagecreatefrompng($orig_image);
$source_imagex = imagesx($source_image);
$source_imagey = imagesy($source_image);
$dest_imagex = 800;
$dest_imagey = 800;
$dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);
imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0,
$dest_imagex, $dest_imagey, $source_imagex, $source_imagey);
imagejpeg($dest_image, $orig_image, 100);
}
I used to do this by percentages although now I am looking to do it by Pixels instead, although after trial, the images don't seem to be resizing? And I am not sure why?
$get_resize_width = '225';
$get_resize_height = '150';
$info = getimagesize($file);
list($width, $height) = getimagesize($file);
$new_width = $get_resize_width;
$new_height = $get_resize_height;
if ($info['mime'] == 'image/jpeg') $image = imagecreatefromjpeg($file);
elseif ($info['mime'] == 'image/gif') $image = imagecreatefromgif($file);
elseif ($info['mime'] == 'image/png') $image = imagecreatefrompng($file);
$image = imagecreatetruecolor($new_width, $new_height);
$photo = imagecreatefromjpeg($file);
imagecopyresampled($image, $photo, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagejpeg($image, $newfile, $img_quality);
$origional_image = $file;
$compressed_image = $newfile;
I have tried adding px to the end of the variables although this doesn't seem to make a difference?
I created a function that takes images, resizes them to fit at least one dimension perfectly onto a canvas and finally crops out excess image content.
Process:
Take a 640x400 image
Scale image fit into 450x450 canvas (image is now 450x281)
Crop out excess data if any
The problem I'm encountering currently involves images that are too small for the newly created thumbnail (such as the one provided in the example above). I expected the output to either have a white background(JPGs) or a transparent background(PNGs). However, despite my best efforts, this tends to be the resulting mess:
As can be observed, the image has a black background in place of a transparent/white background. I am completely stumped on how to correct this flaw.
A copy of my code:
function create_thumbnail($path, $saveto, $width, $height) {
ini_set('memory_limit', '128M'); //Unlocking more memory for download
$info = getimagesize($path);
$rate = $info[0]/$info[1];
// Determine image size/position
if ($info[0] < $width || $info[1] < $height) {
// Image is too small
if ($info[0] < $width && $info[1] < $height) {
// Both width and height too small
$nw = $info[0];
$nh = $info[1];
} else if ($info[0] < $width) {
// Width is too small
$nw = ($info[0]*$height)/$info[1];
$nh = $height;
} else if ($info[1] < $height) {
// Height is too small
$nw = $width;
$nh = ($info[1]*$width)/$info[0];
}
} else {
// Image fits
if (($width/$height) > $rate) {
$nw = $width;
$nh = $width/$rate;
} else {
$nw = $height*$rate;
$nh = $height;
}
}
$nw = round($nw);
$nh = round($nh);
$x_mid = round($nw/2);
$y_mid = round($nh/2);
switch($info[2]) {
case IMAGETYPE_PNG :
$src = imagecreatefrompng($path);
break;
case IMAGETYPE_JPEG :
$src = imagecreatefromjpeg($path);
break;
case IMAGETYPE_GIF :
$src = imagecreatefromgif($path);
break;
default :
return false;
}
// Create image
$proc = imagecreatetruecolor($nw, $nh);
$clr = imagecolorallocate($proc, 255, 255, 255);
imagefill($proc, 0, 0, $clr);
imagecopyresampled($proc, $src, 0, 0, 0, 0, $nw, $nh, $info[0], $info[1]);
$thmb = imagecreatetruecolor($width, $height);
$clr = imagecolorallocate($thmb, 255, 255, 255);
imagefill($thmb, 0, 0, $clr);
imagecopyresampled($thmb, $proc, 0, 0, ($x_mid-($width/2)), ($y_mid-($height/2)), $width, $height, $width, $height);
if ($info[2] == IMAGETYPE_PNG || $info[2] == IMAGETYPE_GIF) {
$trnprt_idx = imagecolortransparent($src);
if ($trnprt_idx >= 0) {
// Attempt to forcefully correct transparencies using original image's color index
$trnprt_clr = imagecolorsforindex($src, $trnprt_idx);
$trnprt_idx = imagecolorallocate($thmb, $trnprt_clr['red'], $trnprt_clr['green'], $trnprt_clr['blue']);
imagefill($thmb, 0, 0, $trnprt_idx);
imagecolortransparent($thmb, $trnprt_idx);
imagealphablending($thmb, false);
imagesavealpha($thmb, true);
} else if ($info[2] == IMAGETYPE_PNG) {
// Attempt to forcefully correct transparencies by shutting down blending
$clr = imagecolorallocatealpha($thmb, 0, 0, 0, 127);
imagefill($thmb, 0, 0, $clr);
imagealphablending($thmb, false);
imagesavealpha($thmb, true);
}
}
switch($info[2]) {
case IMAGETYPE_PNG :
imagepng($thmb, $saveto);
break;
case IMAGETYPE_JPEG :
imagejpeg($thmb, $saveto, 100);
break;
case IMAGETYPE_GIF :
imagegif($thmb, $saveto);
break;
default :
return false;
}
return true;
} //End of create_thumbnail()
I have attempted to correct the transparency/coloring (as visible in my code), but it only affects one side of the image. Everything I have tried has either resulting in one side having a transparent/white background or both sides being completely black.
After a long time spent playing around trying to figure out what exactly was going on and breaking, I have found the solution.
The problem is here:
$proc = imagecreatetruecolor($nw, $nh);
$clr = imagecolorallocate($proc, 255, 255, 255);
imagefill($proc, 0, 0, $clr);
imagecopyresampled($proc, $src, 0, 0, 0, 0, $nw, $nh, $info[0], $info[1]);
$thmb = imagecreatetruecolor($width, $height);
$clr = imagecolorallocate($thmb, 255, 255, 255);
imagefill($thmb, 0, 0, $clr);
imagecopyresampled($thmb, $proc, 0, 0, ($x_mid-($width/2)), ($y_mid-($height/2)), $width, $height, $width, $height);
The newly created image $proc was not transferring it's transparency over to $thmb when I was doing imagecopyresampled from one to the other. The solution I found was to either skip creating/using $thmb altogether, or to save $proc as a png/gif first, then use that saved image for imagecopyresample.
I've adapted this code that I found. It resizes .jpg and .png images, and maintains alpha layers.
When I resize an image, however, the reduction in file size is far more than I had anticipated. This isn't a problem for me, as I cannot see with my eyes any degradation or data loss.
What is causing the huge compression of the file, and if I ever needed to, how can I avoid it?
function thumbnail($image, $width, $height, $target) {
if($image[0] != "/") { // Decide where to look for the image if a full path is not given
if(!isset($_SERVER["HTTP_REFERER"])) { // Try to find image if accessed directly from this script in a browser
$image = $_SERVER["DOCUMENT_ROOT"].implode("/", (explode('/', $_SERVER["PHP_SELF"], -1)))."/".$image;
} else {
$image = implode("/", (explode('/', $_SERVER["HTTP_REFERER"], -1)))."/".$image;
}
} else {
$image = $_SERVER["DOCUMENT_ROOT"].$image;
}
$image_properties = getimagesize($image);
$image_width = $image_properties[0];
$image_height = $image_properties[1];
$image_ratio = $image_width / $image_height;
$type = $image_properties["mime"];
if(!$width && !$height) {
$width = $image_width;
$height = $image_height;
}
if(!$width) {
$width = round($height * $image_ratio);
}
if(!$height) {
$height = round($width / $image_ratio);
}
if($type == "image/jpeg") {
header('Content-type: image/jpeg');
$thumb = imagecreatefromjpeg($image);
} elseif($type == "image/png") {
header('Content-type: image/png');
$thumb = imagecreatefrompng($image);
} else {
return false;
}
$temp_image = imagecreatetruecolor($width, $height);
imagealphablending($temp_image, false);
imagesavealpha($temp_image,true);
$transparent = imagecolorallocatealpha($temp_image, 255, 255, 255, 127);
imagefilledrectangle($temp_image, 0, 0, $nWidth, $nHeight, $transparent);
imagecopyresampled($temp_image, $thumb, 0, 0, 0, 0, $width, $height, $image_width, $image_height);
//$thumbnail = imagecreatetruecolor($width, $height);
//imagecopyresampled($thumbnail, $temp_image, 0, 0, 0, 0, $width, $height, $width, $height);
if($type == "image/jpeg") {
imagejpeg($temp_image, 'img/'.$target.'.jpg');
} else {
imagepng($temp_image,'img/'.$target.'.png');
}
imagedestroy($temp_image);
//imagedestroy($thumbnail);
}
As showdev commented, both imagejpeg() and imagepng() accept a third optional parameter for the image quality. For imagejpeg() it runs from 0 to 100 and defaults to 75), for imagepng() it is from 0 to 9 and defaults to 6.
Also, 4.4Mb is a really big size for a ~2.4Mpx image. It problably contains a lot of metadata and most of it -like Photoshop thumbsnails- is not preserved when you do an imagecopyresampled() with PHP's GD library.
You should also run one of your test images through a lossless compression program like JStrip (http://davidcrowell.com/jstrip/), to check how much it weights without the bloat.
Can you help me with my code in php?
I don't know how make my pictures transparent. They have black background after the uploading. I have the code here. (and some text for small post and content)
Thhank you.
<?php
function zmensi_obrazok($image_max_width, $image_max_height, $obrazok, $obrazok_tmp, $obrazok_size, $filename){
$postvars = array(
"image" => $obrazok,
"image_tmp" => $obrazok_tmp,
"image_size" => $obrazok_size,
"image_max_width" => $image_max_width,
"image_max_height" => $image_max_height
);
$valid_exts = array("jpg","jpeg","png");
$ext = end(explode(".",strtolower($obrazok)));
if($postvars["image_size"] <= 1024000){
if(in_array($ext,$valid_exts)){
if($ext == "jpg" || $ext == "jpeg"){
$image = imagecreatefromjpeg($postvars["image_tmp"]);
}
else if($ext == "png"){
$image = imagecreatefrompng($postvars["image_tmp"]);
}
list($width,$height) = getimagesize($postvars["image_tmp"]);
$old_width = imagesx($image);
$old_height = imagesy($image);
$scale = min($postvars["image_max_width"]/$old_width, $postvars["image_max_height"]/$old_height);
$new_width = ceil($scale*$old_width);
$new_height = ceil($scale*$old_height);
$tmp = imagecreatetruecolor($new_width,$new_height);
imagecopyresampled($tmp,$image,0,0,0,0,$new_width,$new_height,$width,$height);
imagejpeg($tmp,$filename,100);
return "";
imagedestroy($image);
imagedestroy($tmp);
}
}
}
?>
I think this link will answer your question:
http://www.php.net/manual/pl/function.imagecopyresampled.php#104028
In your code the answer will be something like:
// preserve transparency
if($ext == "gif" or $ext == "png"){
imagecolortransparent($tmp, imagecolorallocatealpha($tmp, 0, 0, 0, 127));
imagealphablending($tmp, false);
imagesavealpha($tmp, true);
}
Paste this before executing imagecopyresampled.
If you did want to save to a JPEG rather than saving to a PNG, you can just change the background colour of the target image to white before you do the copy:
$tmp = imagecreatetruecolor($new_width,$new_height);
imagefilledrectangle($tmp, 0, 0, $new_width, $new_height, imagecolorallocate($tmp, 255, 255, 255));
imagecopyresampled($tmp,$image,0,0,0,0,$new_width,$new_height,$width,$height);
Then you'll end up with a JPEG without any transparency, but the background colour will be white rather than black.