I'm generating thumbnail images from the original jpeg files when they are being uploaded. I could actually create and move those thumbnail files to another directory, but the problem is that those thumbnail files displays only the black color while uploading.
My code.
if(isset($_POST['upload'])){
$img = $_FILES['origin']['name'];
move_uploaded_file($_FILES['origin']['tmp_name'], 'image/'.$img);
define("SOURCE", 'image/');
define("DEST", 'thumb/');
define("MAXW", 120);
define("MAXH", 90);
$jpg = SOURCE.$img;
if($jpg){
list($width, $height, $type) = getimagesize($jpg); //$type will return the type of the image
if(MAXW >= $width && MAXH >= $height){
$ratio = 1;
}elseif($width > $height){
$ratio = MAXW / $width;
}else{
$ratio = MAXH / $height;
}
$thumb_width = round($width * $ratio); //get the smaller value from cal # floor()
$thumb_height = round($height * $ratio);
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
$path = DEST.$img."_thumb.jpg";
imagejpeg($thumb, $path);
echo "<img src='".$path."' alt='".$path."' />";
}
imagedestroy($thumb);
}
and the thumbnail file looks like this:
From php manual:
imagecreatetruecolor() returns an image identifier representing a black image of the specified size.
So the problem is that you actually create this black image and save it.
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
For solution on resizing, please refer to this question on stackoverflow.
Hmm, I just found my bug right now. The problem is that I use $jpg = SOURCE.$img; instead of $jpg = imagecreatefromjpeg($jpg); and also I need to copy the sample image to the new thumbnail image using
imagecopyresampled( $thumb, $jpg, 0, 0, 0, 0, $thumb_width, $thumb_height, $width, $height );
Then it works!!!
Thanks Alex for your answer which lead me to this solution.
Related
I am testing a thumbnail image creator script which creates a thumbnail that can be displayed in the web browser without saving it first.
Currently I have to use the following code to display the image:
include('image.inc.php');
header('Content-Type: image/png');
create_thumbnail('me.jpg', false, 200, 200);
But how can I display the dynamically generated thumbnail image on a standard webpage along side html mark-up?
create_thumbnail function:
function create_thumbnail($path, $save, $width, $height){
// Get the width[0] and height[1] of image in an array
$info = getimagesize($path);
// Create a new array that just contains the width and height
$size = array($info[0], $info[1]);
// Check what file type the image is
if($info['mime'] == 'image/png'){
$src = imagecreatefrompng($path);
}else if($info['mime'] == 'image/jpeg'){
$src = imagecreatefromjpeg($path);
}else if($info['mime'] == 'image/gif'){
$src = imagecreatefromgif($path);
}else{
// If it isn't a good file type don't do anything
return false;
}
// Create a thumbnail with the passed dimensions
$thumb = imagecreatetruecolor($width, $height);
$src_aspect = $size[0] / $size[1];
$thumb_aspect = $width / $height;
if($src_aspect < $thumb_aspect){
// Image is tall
$scale = $width / $size[0];
$new_size = array($width, $width / $src_aspect);
$src_pos = array(0, ($size[1] * $scale - $height) / $scale / 2);
}else if($src_aspect > $thumb_aspect){
// Image is wide
$scale = $height / $size[1];
$new_size = array($height * $src_aspect, $height);
$src_pos = array(($size[0] * $scale - $width) / $scale /2, 0);
}else{
// Image is square
$new_size = array($width, $height);
$src_pos = array(0, 0);
}
// Stop the new dimensions being less than 1 (this stops it breaking the code). Takes which ever value is higher.
$new_size[0] = max($new_size[0], 1);
$new_size[1] = max($new_size[1], 1);
// Copy the image into the new thumbnail
// Newly created thumbnail, image copying from, starting x-coord of thumbnail, starting y-coord of thumbnail(0,0 will fill up entire thumbnail), x-coord of original image, y-coord of original image, width of new thumbnail, height of new thumbnail, width of original image, height of original image
imagecopyresampled($thumb, $src, 0, 0, $src_pos[0], $src_pos[1], $new_size[0], $new_size[1], $size[0], $size[1]);
if($save === false){
return imagepng($thumb);
}else{
// Create the png image and save it to passed location
return imagepng($thumb, $save);
}
If I understand your question correctly, you just need to insert an img tag and set its src attribute to your php script.
Something like:
<img src="thumbnailgenerator.php?image_path=me.jpg">
Convert it to base64 (using base64_encode) and then display it with:
<img src="data:image/jpg;base64,iVBORw0KGgoAAAANS==" />
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.
I am creating thumbnails of fixed height and width from my PHP script using the following function
/*creates thumbnail of required dimensions*/
function createThumbnailofSize($sourcefilepath,$destdir,$reqwidth,$reqheight,$aspectratio=false)
{
/*
* $sourcefilepath = absolute source file path of jpeg
* $destdir = absolute path of destination directory of thumbnail ending with "/"
*/
$thumbWidth = $reqwidth; /*pixels*/
$filename = split("[/\\]",$sourcefilepath);
$filename = $filename[count($filename)-1];
$thumbnail_path = $destdir.$filename;
$image_file = $sourcefilepath;
$img = imagecreatefromjpeg($image_file);
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
if($aspectratio==true)
{
$new_height = floor( $height * ( $thumbWidth / $width ) );
}
else
{
$new_height = $reqheight;
}
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// save thumbnail into a file
$returnvalue = imagejpeg($tmp_img,$thumbnail_path);
imagedestroy($img);
return $returnvalue;
}
and I call this function with following parameters
createThumbnailofSize($sourcefilepath,$destdir,48,48,false);
but the problem is the resulting image is of very poor quality, when I perform the same operation with Adobe Photo shop, it performs a good conversion.. why it is so? I am unable to find any quality parameter, through which I change the quality of output image..
Use imagecopyresampled() instead of imagecopyresized().
if it is image quality you are after you need to give the quality parameter when you save the image using imagejpeg($tmp_img,$thumbnail_path,100) //default value is 75
/*creates thumbnail of required dimensions*/
function
createThumbnailofSize($sourcefilepath,$destdir,$reqwidth,$reqheight,$aspectratio=false)
{
/*
* $sourcefilepath = absolute source file path of jpeg
* $destdir = absolute path of destination directory of thumbnail ending with "/"
*/
$thumbWidth = $reqwidth; /*pixels*/
$filename = split("[/\\]",$sourcefilepath);
$filename = $filename[count($filename)-1];
$thumbnail_path = $destdir.$filename;
$image_file = $sourcefilepath;
$img = imagecreatefromjpeg($image_file);
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
if($aspectratio==true)
{
$new_height = floor( $height * ( $thumbWidth / $width ) );
}
else
{
$new_height = $reqheight;
}
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// save thumbnail into a file
$returnvalue = imagejpeg($tmp_img,$thumbnail_path,100);
imagedestroy($img);
return $returnvalue;
}
You could also consider using ImageMagick (http://us3.php.net/manual/en/book.imagick.php) instead of Gd. I had the same problem just a couple of days ago with Java. Going for ImageMagick instead of Java Advanced Images resultet in a huge quality difference.
tried using the php.Thumbnailer ?
$thumb=new Thumbnailer("photo.jpg");
$thumb->thumbSquare(48)->save("thumb.jpg");
Result photo will be 48x48px. Easy right? :)
You might also want to take a look at the Image_Transform PEAR package. It takes care of a lot of the low-level details for you and makes creating and manipulating images painless. It also lets you use either GD or ImageMagick libraries. I've used it with great success on several projects.
here is the website im talking about
http://makeupbyarpi.com/portfolio.php
you'll notice some of the images are smushed width-wise.
the code i used is this:
$width="500";
$height="636";
$img_src = $_FILES['galleryimg']['tmp_name'];
$thumb = "../gallery/".rand(0,100000).".jpg";
//Create image stream
$image = imagecreatefromjpeg($img_src);
//Gather and store the width and height
list($image_width, $image_height) = getimagesize($img_src);
//Resample/resize the image
$tmp_img = imagecreatetruecolor($width, $height);
imagecopyresampled($tmp_img, $image, 0, 0, 0, 0, $width, $height, $image_width, $image_height);
//Attempt to save the new thumbnail
if(is_writeable(dirname($thumb))){
imagejpeg($tmp_img, $thumb, 100);
}
//Free memory
imagedestroy($tmp_img);
imagedestroy($image);
the images that get uploaded are huge sometimes 3000px by 2000px and i have php crop it down to 500 x 536 and some landscape based images get smushed. is there a formula i can use to crop it carefully so that the image comes out good?
thanks
You could resize and add a letterbox if required. You simply need to resize the width and then calculate the new height (assuming width to height ratio is same as original) then if the height is not equal to the preferred height you need to draw a black rectangle (cover background) and then centre the image.
You could also do a pillarbox, but then you do the exact same as above except that width becomes height and height becomes width.
Edit: Actually, you resize the one that is the biggest, if width is bigger, you resize that and if height is bigger then you resize that. And depending on which one you resize, your script should either letterbox or pillarbox.
EDIT 2:
<?php
// Define image to resize
$img_src = $_FILES['galleryimg']['tmp_name'];
$thumb = "../gallery/" . rand(0,100000) . ".jpg";
// Define resize width and height
$width = 500;
$height = 636;
// Open image
$img = imagecreatefromjpeg($img_src);
// Store image width and height
list($img_width, $img_height) = getimagesize($img_src);
// Create the new image
$new_img = imagecreatetruecolor($width, $height);
// Calculate stuff and resize image accordingly
if (($width/$img_width) < ($height/$img_height)) {
$new_width = $width;
$new_height = ($width/$img_width) * $img_height;
$new_x = 0;
$new_y = ($height - $new_height) / 2;
} else {
$new_width = ($height/$img_height) * $img_width;
$new_height = $height;
$new_x = ($width - $new_width) / 2;
$new_y = 0;
}
imagecopyresampled($new_img, $img, $new_x, $new_y, 0, 0, $new_width, $new_height, $img_width, $img_height);
// Save thumbnail
if (is_writeable(dirname($thumb))) {
imagejpeg($new_img, $thumb, 100);
}
// Free up resources
imagedestroy($new_img);
imagedestroy($img);
?>
Sorry it took a while, I ran across a small bug in the calculation part which I was unable to fix for like 10 minutes =/ This should work.
I'd like crop an image in PHP and save the file. I know your supposed to use the GD library but i'm not sure how. Any ideas?
Thanks
You could use imagecopy to crop a required part of an image. The command goes like this:
imagecopy (
resource $dst_im - the image object ,
resource $src_im - destination image ,
int $dst_x - x coordinate in the destination image (use 0) ,
int $dst_y - y coordinate in the destination image (use 0) ,
int $src_x - x coordinate in the source image you want to crop ,
int $src_y - y coordinate in the source image you want to crop ,
int $src_w - crop width ,
int $src_h - crop height
)
Code from PHP.net - a 80x40 px image is cropped from a source image
<?php
// Create image instances
$src = imagecreatefromgif('php.gif');
$dest = imagecreatetruecolor(80, 40);
// Copy
imagecopy($dest, $src, 0, 0, 20, 13, 80, 40);
// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);
imagedestroy($dest);
imagedestroy($src);
?>
This function will crop image maintaining image aspect ratio :)
function resize_image_crop($image, $width, $height)
{
$w = #imagesx($image); //current width
$h = #imagesy($image); //current height
if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
$ratio = $width / $w; //try max width first...
$new_w = $width;
$new_h = $h * $ratio;
if ($new_h < $height) { //if that created an image smaller than what we wanted, try the other way
$ratio = $height / $h;
$new_h = $height;
$new_w = $w * $ratio;
}
$image2 = imagecreatetruecolor ($new_w, $new_h);
imagecopyresampled($image2,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
if (($new_h != $height) || ($new_w != $width)) { //check to see if cropping needs to happen
$image3 = imagecreatetruecolor ($width, $height);
if ($new_h > $height) { //crop vertically
$extra = $new_h - $height;
$x = 0; //source x
$y = round($extra / 2); //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
} else {
$extra = $new_w - $width;
$x = round($extra / 2); //source x
$y = 0; //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
}
imagedestroy($image2);
return $image3;
} else {
return $image2;
}
}
To crop an image using GD you need to use a combination of GD methods, and if you look at "Example #1" on PHP's documentation of the imagecopyresampled method, it shows you how to crop and output an image, you would just need to add some code to that to capture and write the output to a file...
http://us2.php.net/manual/en/function.imagecopyresampled.php
There are also other options, including Image Magick which, if installed on your server, can be accessed directly using PHP's exec method (or similar) or you can install the PHP Imagick extension, which yields higher quality images and, in my opinion, is a little more intuitive and flexible to work with.
Finally, I've used the open source PHPThumb class library, which has a pretty simple interface and can work with multiple options depending on what's on your server, including ImageMagick and GD.
I use this script in some projects and it's pretty easy to use:
http://shiftingpixel.com/2008/03/03/smart-image-resizer/
The script requires PHP 5.1.0 (which is out since 2005-11-24 - time to upgrade if not yet at this version) and GD (which is rarely missing from good Web hosts).
Here is an example of it's use in your HTML:
<img src="/image.php/coffee-bean.jpg?width=200&height=200&image=/wp-content/uploads/2008/03/coffee-bean.jpg" alt="Coffee Bean" />
I just created this function and it works for my needs, creating a centered and cropped thumbnail image. It is streamlined and doesn't require multiple imagecopy calls like shown in webGautam's answer.
Provide the image path, the final width and height, and optionally the quality of the image. I made this for creating thumbnails, so all images are saved as JPGs, you can edit it to accommodate other image types if you require them. The main point here is the math and method of using imagecopyresampled to produce a thumbnail. Images are saved using the same name, plus the image size.
function resize_crop_image($image_path, $end_width, $end_height, $quality = '') {
if ($end_width < 1) $end_width = 100;
if ($end_height < 1) $end_height = 100;
if ($quality < 1 || $quality > 100) $quality = 60;
$image = false;
$dot = strrpos($image_path,'.');
$file = substr($image_path,0,$dot).'-'.$end_width.'x'.$end_height.'.jpg';
$ext = substr($image_path,$dot+1);
if ($ext == 'jpg' || $ext == 'jpeg') $image = #imagecreatefromjpeg($image_path);
elseif($ext == 'gif') $image = #imagecreatefromgif($image_path);
elseif($ext == 'png') $image = #imagecreatefrompng($image_path);
if ($image) {
$width = imagesx($image);
$height = imagesy($image);
$scale = max($end_width/$width, $end_height/$height);
$new_width = floor($scale*$width);
$new_height = floor($scale*$height);
$x = ($new_width != $end_width ? ($width - $end_width) / 2 : 0);
$y = ($new_height != $end_height ? ($height - $end_height) / 2 : 0);
$new_image = #imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($new_image,$image,0,0,$x,$y,$new_width,$new_height,$width - $x,$height - $y);
imagedestroy($image);
imagejpeg($new_image,$file,$quality);
imagedestroy($new_image);
return $file;
}
return false;
}
You can use below method to crop image,
/*parameters are
$image =source image name
$width = target width
$height = height of image
$scale = scale of image*/
function resizeImage($image,$width,$height,$scale) {
//generate new image height and width of source image
$newImageWidth = ceil($width * $scale);
$newImageHeight = ceil($height * $scale);
//Create a new true color image
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
//Create a new image from file
$source = imagecreatefromjpeg($image);
//Copy and resize part of an image with resampling
imagecopyresampled($newImage,$source,0,0,0,0,$newImageWidth,$newImageHeight,$width,$height);
//Output image to file
imagejpeg($newImage,$image,90);
//set rights on image file
chmod($image, 0777);
//return crop image
return $image;
}