I'm creating a function to crop images using PHP GD.
The function works perfectly for JPEG images but when I try to use the same function for PNG I just get a blank page and the following errors when I inspect the page in chrome:
I realize this is a javascript error, but this is probably something chrome does? This is what happens when i visit the IMAGE URL. If i replicate this with the JPEG code it works perfectly.
Edit: in Firefox it says "The image [URL] cannot be displayed because it contains errors. The below js error is just a chrome error and isn't very relevant.
Uncaught TypeError: Cannot read property 'getAttribute' of null
data_loader.js:2 Uncaught TypeError: Cannot read property
'hasAttribute' of null global-shortcut.js:9
The working JPEG code is as follows:
$fileName = $_POST['file'];
$jpeg_quality = 100;
$ratio = $_POST['r'];
$src = '/var/www/admin/public_html/images/'.$fileName;
$image = imagecreatefromjpeg($src);
$target = '/var/www/admin/public_html/images/crop/'.$fileName;
$thumb_width = $_POST['w'] / $ratio;
$thumb_height = $_POST['h'] / $ratio;
$width = imagesx($image);
$height = imagesy($image);
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0,
0,
$_POST['x'] / $ratio, $_POST['y'] / $ratio,
$width, $height,
$width, $height);
imagejpeg($thumb, $target, $jpeg_quality);
The Broken PNG code is as follows:
$fileName = $_POST['file'];
$jpeg_quality = 100;
$ratio = $_POST['r'];
$src = '/var/www/admin/public_html/images/'.$fileName;
$image = imagecreatefrompng($src);
$target = '/var/www/admin/public_html/images/crop/'.$fileName;
$thumb_width = $_POST['w'] / $ratio;
$thumb_height = $_POST['h'] / $ratio;
$width = imagesx($image);
$height = imagesy($image);
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0,
0,
$_POST['x'] / $ratio, $_POST['y'] / $ratio,
$width, $height,
$width, $height);
imagepng($thumb, $target, $jpeg_quality);
I answered my own question.
imagepng() function takes quality argument from 0 to 9
imagejpeg() function takes quality argument from 0 to 100
Related
Hy there,
I use this code to resize my images to improve size...
<?php
// File
$filename = 'ok.jpg';
list($width, $height) = getimagesize($filename);
$ratio = ($width >= $height) ? 683 : 1152;
$percent = $ratio / $height;
// New sizes
$new_width = $width * $percent;
$new_height = $height * $percent;
// Apply new sizes
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// Save
imagejpeg($image_p, 'tes.jpg', 80);
imagedestroy($image);
imagedestroy($image_p);
But I saw a problem with the colors quality... image looks more grey than original.
Original picture :
And after resizing :
What can I do to keep same colors ?
Thanks
I am using following php function to crop a image. When a image is cropped then the image background is look like a blurry. Like bellow image. It's should be solid white background color :
Blurry Image :
Php code is bellow :
function crop_image ($target, $newcopy, $w, $h, $ext) {
$ext = strtolower($ext);
if ($ext == "gif"){
$image = imagecreatefromgif($target);
} else if($ext =="png"){
$image = imagecreatefrompng($target);
} else {
$image = imagecreatefromjpeg($target);
}
$filename = $newcopy;
$thumb_width = $w;
$thumb_height = $h;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
$color = imagecolorallocate($thumb, 255, 255, 255);
imagefill($thumb, 0, 0, $color);
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
}
You're feeding a $quality value of 80 into imagejpeg. JPEG is a lossy format. This results in artifacts like the ones you're seeing:
quality is optional, and ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file). The default is the default IJG quality value (about 75).
Try using a higher value:
imagejpeg($thumb, $filename, 90);
The maximum value for $quality is 100.
I am trying to crop and resize the images. When images moved to the resized_images folder all images are turn to black but images are resized(535 * 313). Here is my code i have tried so far. Can you please suggest me right way to do this.? thank u
<form action="" method="POST" enctype="multipart/form-data">
<input id="input-6" name="slideshow_images[]" type="file" multiple class="file-loading">
<input type="submit" name="sub" >
</form>
<?php
if(isset($_POST['sub']))
{
$pic = $_FILES["slideshow_images"]["name"];
foreach($pic as $pic_src)
{
$image = imagecreatefromjpeg($pic_src);
$filename = 'resized_images/'.$pic_src.'cropped_whatever.jpeg';
$thumb_width = 535;
$thumb_height = 313;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
}
}
?>
Change your code lines to:
$pic = $_FILES["slideshow_images"]["tmp_name"];
$image = imagecreatefromstring(file_get_contents(($pic_src)));
Because ["name"] is only 123.jpg, it is not object.
The best way will be that:
<form action="" method="POST" enctype="multipart/form-data">
<input id="input-6" name="slideshow_images[]" type="file" multiple class="file-loading">
<input type="submit" name="sub" >
</form>
<?php
if(isset($_POST['sub'])){
if(isset($_FILES['slideshow_images'])){
foreach ($_FILES["slideshow_images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["slideshow_images"]["tmp_name"][$key];
$name = $_FILES["slideshow_images"]["name"][$key];
$image = imagecreatefromstring(file_get_contents(($tmp_name)));
$filename = 'images/'.$name.'cropped_whatever.jpg';
$thumb_width = 535;
$thumb_height = 313;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
}
}
}
}
?>
Also, If you don't want to add ".jpg" in filename, replace $filename row to this:
$filename = 'images/'.preg_replace('/\.[^.]*$/', '', $name).'cropped_whatever.jpg';
I just ran into this problem. What the problem is is the background color is black and totally transparent. What you have to do is just allocate a true color (like white) with alpha and make the alpha totally non-transparent. Then just do a filled rectangle over the new area first and your image should then show up. :-)
The following is directly out of the php documentation about imagecopy:
// create new image with padding
$img = imagecreatetruecolor($right-$left+$padding*2,$bottom-$top+$padding*2);
// Allocate background color
$white = imagecolorallocatealpha( $img, 255, 255, 255, 0 );
// fill the background
imagefill($img, 0, 0, $white);
// or use
imagefilledrectangle( $img, 0,0,$width,$height, $white );
// copy
imagecopy($img, $image, $padding, $padding, $left, $top, $right-$left, $bottom-$top);
Notice that they do an imagefill with the background color before actually copying the new image. It is the same for the imagecopyresample.
Well, unlike before - this time I didn't get a black image. So check what you do against the following: In fact, download the following and run it (along with the test.jpg image). See if it works for you. Please note that this is directly out of the PHP Documentation website for imagecopyresample.
<?php
// The file
$filename = './test.jpg';
$percent = 0.5;
// Content type
header('Content-Type: image/jpeg');
// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;
// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// Output
imagejpeg($image_p, "new.jpg", 100);
?>
And here is the image:
And here is the output:
Im having issue when a user uploads and try's to crop a PNG or transparent image( with .gif)
I am getting:
Warning: imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable error: in statusUpFunctions.php on line 100
Warning: imagecreatefromjpeg(): 'images/status/photo/1-6.jpg' is not a valid JPEG file in statusUpFunctions.php on line 100
Warning: imagecopyresampled() expects parameter 2 to be resource, boolean given in statusUpFunctions.php on line 114
This may be because of my php crop function:
case 'crop':
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
ini_set('memory_limit', '256M');
$jpeg_quality = 90;
$src = "images/status/photo/".$_POST['fname'];
$img_r = imagecreatefromjpeg($src);
if($_POST['fixed'] == 0) {
$targ_w = $_POST['w'];
$targ_h = $_POST['h'];
}
else {
$targ_h = $_POST['sizeh'];
$targ_w = $_POST['sizew'];
}
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
$targ_w,$targ_h,$_POST['w'],$_POST['h']);
$path_thumbs = "images/status/photo";
$filename = $newfilename;
$thumb_path = $path_thumbs . '/' . $filename;
imagejpeg($dst_r,$thumb_path,$jpeg_quality);
}
break;
}
It creates from jpg, cant i make so it creates from gif and png and bmp and so..? and then convert it somehow..
How should this be solved?
The function imagecreatefromjpeg() creates a generic PHP image object from a jpeg image. You can then do whatever you want with the object.
imagecreatefromjpeg() will ONLY create a generic image object FROM a JPEG. If you want to create a generic image object FROM a PNG or GIF, you need to use their respective functions: imagecreatefrompng() and imagecreatefromgif(). One quick way to detect an image's type is by reading its file extension.
Once you have that generic image object, then you can do what you want with it (including using imagecopyresampled()), and then create a jpeg image from it using imagejpeg().
EDIT:
You can use pathinfo() to detect the file's extension:
$filename = pathinfo($_POST['fname']); // Returns an array of file details
$extension = $filename['extension'];
If you are getting the filename from a $_POST value, you need to make sure that you are copying the temporary image file to that filename. I don't see any $_FILES values used in your code (maybe you're doing it in another script?). If not, here's a good tutorial on handling file uploads. It also covers file extensions.
Try This... It will work..
<?php
$image = imagecreatefrompng('photo.png');
$thumb_width = 280;
$thumb_height = 200;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect ){
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}else{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$crop = imagecreatetruecolor($thumb_width,$thumb_height);
imagealphablending($crop, false);
$white = imagecolorallocatealpha($crop, 0, 0, 0, 127); //FOR WHITE BACKGROUND
imagefilledrectangle($crop,0,0,$thumb_width,$thumb_height,$white);
imagesavealpha($crop, true);
$userImage = imagecopyresampled($crop, $image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0, $new_width, $new_height,
$width, $height);
header('Content-type: image/png');
imagepng($crop);
?>
It fails to load the image, causing imagecreatefromjpeg() to return false. Make sure that you're trying to open an valid image.
For gif and png files you need to get the image identifier using imagecreatefromgif and imagecreatefrompng
<?php
$image = imagecreatefrompng('myPhoto.png');
$crop = imagecreatetruecolor(50,50);
$userImage = imagecopyresampled($crop, $image, 0, 0, 0, 0, 50, 50, 8, 8);
header('Content-type: image/png');
imagepng($crop);
?>
This will return cropped image.
The problem: When converting any PNG image into a JPEG, the image turns all black.
To start off, I've searched the internet and stackoverflow to find out how to do this. I've tried every method I could find in the PHP Manual and on Stack Overflow. The problem still exists. I'm using GD (don't have ImageMagick installed).
My code is below. This is the call to the function:
$tempImage = $dirPath.$filename.$tempMini.".jpg";
createTempImage($sourcefile, $tempImage, $tempMini_width, $tempMini_height, 100);
I've commented out the different methods that I've tried.
function createTempImage($sourcefile, $setNewName, $maxwidth, $maxheight, $quality){
$fileInfoArray = getimagesize($sourcefile);
$imagetype = $fileInfoArray['mime'];
if($imagetype == 'image/jpeg'){
$img = imagecreatefromjpeg($sourcefile);
}elseif($imagetype == 'image/gif'){
$img = imagecreatefromgif($sourcefile);
}elseif(($imagetype == 'image/png')||($imagetype == 'image/x-png')){
$img = imagecreatefrompng($sourcefile);
}
$width = imagesx( $img );
$height = imagesy( $img );
if ($width > $maxwidth || $height > $maxheight){
$factor = min(($maxwidth/$width),($maxheight/$height));
$newwidth = round($width*$factor);
$newheight = round($height*$factor);
} else {
$newwidth = $width;
$newheight = $height;
}
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
imagecopyresampled($tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );
imagejpeg($tmpimg, $setNewName, 100);
imagedestroy($tmpimg);
imagedestroy($img);
}
The following have also been attempted:
$white = imagecolorallocate($tmpimg, 255, 255, 255);
ImageFill($tmpimg, 0, 0, $white);
ImageSaveAlpha($tmpimg, false);
ImageAlphaBlending($tmpimg, false);
$white = imagecolorallocate($tmpimg, 255, 255, 255);
imagefilledrectangle($tmpimg, 0, 0, $newwidth, $newheight, $white);
Update: The top black box is the image result: http://twitpic.com/30ywf5
Just a couple of ideas:
$newHeight = $maxheight; seems to be a typo, "newheight" is spelled without the capital "H" throughout the code.
The code to determine the new size can be shortened sigificantly:
if ($width > $maxwidth || $height > $maxheight){
$factor = min(($maxwidth/$width),($maxheight/$height));
$newwidth = round($width*$factor);
$newheight = round($height*$factor);
}
You use imagecopyresampled to create the new image - this only works in specific GD-versions ("version 2"), try to use imagecopyresized otherwise.
I seemed to have fixed the problem by recreating the whole function from scratch. Thank you guys for your input.
The problem was that PNG's weren't being uploaded. When executing the script with already uploaded URLs, it worked fine.
Thanks again.