PHP create thumbnail from uploaded file and moving to server - php

I have encountered a problem with creating a thumbnail from an uploaded image file, then to upload it to the server.
As of now, I have a function that creates the thumbnail, saves it as a temp and returns it to the caller.
Then what I try to do, is upload that created thumb image with move_uploaded_file(tempthumb, path);
Here is the createThumb function and the caller:
function createThumb( $image, $thumbWidth )
{
// load image and get image size
$img = imagecreatefromjpeg( "{$image}" );
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// 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);
return $tmp_img;
}
return $tmp_img; // Here I return the new image. Is this the proper way to get a binary image back??
Here is the caller:
$thumb = createThumb($_FILES['propform-previmg']['tmp_name'], $max_previmg_width);
$filenamepath = $src_dir . '/thumb/' . $_FILES['propform-previmg']['name'];
if ( !move_uploaded_file($thumb, $filenamepath ))
echo "Error moving file {$filenamepath}";
I tried to just upload the uploaded file directly without trying to make a thumbnail first, and that worked fine. So I guess there is some error with the variable I return from the createThumb function, but I can't figure out exactly what.
Also, I need to do the upload from the caller code, and not inside the createThumb function with imagejpeg(file, path).
Thank you!

First line from the manual:
This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism). If the file is valid, it will be moved to the filename given by destination.
Your thumbnail wasn't uploaded, it even isn't a file yet, but just an image resource. To write the image, call something like imagejpeg($resource, $filename) to write it to the path specified in $filename.

Related

My thumbnail function is't working properly

When this code runs the browser screen turns black with a grey and white checkered square in the middle when it is suppose to display a thumbnail within a table cell on a form.
function createThumb( $imageUrl, $thumbWidth )
{
// load image and get image size
$img = imagecreatefromjpeg( $imageUrl );
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// 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 );
// display thumbnail
header("Content-type:image/jpeg");
imagejpeg( $tmp_img,$imageUrl,80);
};
And the line that calls the code is
<td >
<?php echo createThumb("CoffeeReg.jpg",75)?>
</td>
I haven't found any of the normal syntax errors, and the code even comes back clean when ran through a syntax checker so that leads me to believe either its a problem with my logic, I'm using the built in functions incorrectly or I have messed up something in the way I am trying to display the new thumbnail only with my lack of exp I don't see where I went wrong. I need to know what I did wrong so I can learn from this mistake.
Okay so after several hours debugging the code that Majid had provided when trying to help me understand where I went wrong with my code I found that the only thing that was needed to make the code he was using work was to add these two lines of code to the end of the secondary php file as shown here...
<?php
$imageUrl = $_GET['file_name'];
$thumbWidth = $_GET['thumb_width'];
// load image and get image size
$mainImage = imagecreatefromjpeg( $imageUrl );
$mainwidth = imagesx( $mainImage );
$mainheight = imagesy( $mainImage );
// calculate thumbnail size
$thumbWidth = intval($mainwidth/4);
$thumbHeight = intval($mainheight/4);;
// create a new temporary image
$tmp_img = imagecreatetruecolor( $thumbWidth, $thumbHeight );
// copy and resize old image into new image
imagecopyresampled( $tmp_img, $mainImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $mainwidth, $mainheight );
// display thumbnail
header("Content-type:image/jpeg");
//Also had to remove the second and third argument from this function
imagejpeg( $tmp_img);
//these following two lines here is what was missing
imagedestroy(tmp_img);
imagedestroy(mainImage);
?>
So I guess that one must clear out the image variables of the thumbnail code or it will break it when it runs. Not sure why removing the two arguments from the imagejpeg function was also needed but it was mentioned in my textbook so i tried it, now with these changes this code works. Thank you Majid for all your help and If your post was still here you would be getting full credit with an up vote and best answer.

Undefined index: extension for folders in PHP

I wanted to have a script which would turn all my images into thumbnails and save these new thumbnails in a new folder.
I had luck an found a code which worked almost perfectly from
http://webcheatsheet.com/php/create_thumbnail_images.php
The only problem is that if there is a folder in the "uploads"-folder (defined at the end of the code) then I get the "Notice: Undefined index: extension".
The code doesn't get stuck and I still get my thumbnails, but the error message is annoying.
I tried to put in an isset-function, but did something wrong as I still didn't manage to stop the script from acting upon the folders. The code doesn't react similarly on any other files, so it seems to be the lack of an extension in the folder-name that bothers the code.
I was able to make it easy and simply remove any folders from the "uploads"-folder and put the thumbnails' path somewhere else, but I'd also like to get it to work without error-messages in case I happen to have folders in these image folders.
// parse path for the extension
$info = pathinfo($pathToImages . $fname);
// continue only if this is a JPEG image
//print_r($info);
if ( strtolower($info['extension']) == 'jpg' ) { // reacts on the folder with no extension name and gives an error
echo "Creating thumbnail for {$fname} <br />";
// load image and get image size
$img = imagecreatefromjpeg( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// 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
imagejpeg( $tmp_img, "{$pathToThumbs}{$fname}" );
}
}
The full code in the link above.
The pathinfo docs explain:
Note:
If the path does not have an extension, no extension element will be
returned
So to avoid the notice you just need to check that value is available before trying to use it:
if( isset($info['extension']) AND strtolower($info['extension']) == 'jpg'){
//do sutff
}
Or instead of isset(...) you could use array_keys_exists('extension', $info).

Image resizing in php? Can't get it to work

I have this code that I have tried creating and don't know what I am doing wrong.
// SET ERROR FLAG
$error = false;
// MAKE SURE FILE IS AN IMAGE
if (!list($width, $height) = getimagesize($_FILES['avatar']['tmp_name'])) {
$error = true;
}
// MAKE SURE FILE COMES FROM FORM
if (!is_uploaded_file($_FILES['avatar']['tmp_name'])) {
$error = true;
}
// MAKE SURE FILESIZE IS NOT OVER 1MB
if (filesize($_FILES['avatar']['tmp_name']) > 1048576) {
$error = true;
}
// TARGER TO SAVE FILE AND CHANGE FILENAME AND FILE TYPE
$target = 'images/avatars/' . md5($user['id']) . '.gif';
// IMAGE RATIO AND RESIZING
$imgRatio = $width / $height;
if ($imgRatio > 1) {
$newWidth = 200;
$newHeight = 200 / $imgRatio;
} else {
$newWidth = 200 * $imgRatio;
$newHeight = 200;
}
$imgResized = imagecreatetruecolor($newWidth, $newHeight);
$newImg = imagecreatefromgif($_FILES['avatar']['tmp_name']);
$newImg = imagecopyresized($imgResized, $newImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// SUCCESSFULL IMAGE UPLOAD
if (!$error && move_uploaded_file($newImg, $target)) {
echo '<p>Your avatar was uploaded successfully.</p>';
// ERROR UPLOADING IMAGE
} else {
echo '<p>There was an error uploading your avatar.</p>';
}
It always fails I cannot get the resizing to work, even a link to a good tutorial will suffice,
Happy new year!!
I think the problem is that you use GD to open the temporary image file:
$newImg = imagecreatefromgif($_FILES['avatar']['tmp_name']);
$newImg = imagecopyresized($imgResized, $newImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
And then you try to move the temporary avatar file with move_uploaded_file without freeing GD resource and also discarding all the work done with GD (the resizing I mean, and I can add here you have to use resample instaead of resize method).
if (!$error && move_uploaded_file($newImg, $target)) {
The code moves the temporary uploaded file (currently opened by GD and however not physically altered by your GD work, so not resized) to the $target path.
Edit. Now I see more errors with your code. You cannot do:
$newImg = imagecopyresized($imgResized, $newImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
Because imagecopyresized do not returns anything but true or false. It simply copy one portion of a source image to a different destination resource. It do not return a resource itself!
Finally. The correct workflow to the what you want to do is:
Check the uploaded file if it's ok for you (and you do it good, it seems).
Create a $img GD resource opening the uploaded file with imagecopyresized.
Create an empty destination resource $newImg with imagecreatetruecolor.
Resize or resample using imagecopyresized or imagecopyresampled to copy source image to destination resource.
Save destination resource into a GIF file using imagegif.
Discard temporary source uploaded image.
You can learn more googling something like php gd resize uploaded images. Tons of tutorial will be one click far from you.
The code itself looks alright, however there could be a number reasons why it fails. Some debug output would be helpful. Some general pointers:
check that the path for the tmp_name is set and readable
check your php settings for post_max_size, it may be set very low or not set at all.
in your code you are only handling gif type images (imagecreatefromgif), you may need to check for the filetype prior to reading from the image resource
check that GD is properly installed in your php installation (phpinfo(); in a php script or php -i from command line should display it as acticated)
That being sad, add some error messages to your output so we can help further.

imagejpeg() doesnt give the output properly in php

I want to upload an image from disk, resize it, and then upload it to Amazon S3.
However, I cant get the proper image output from imagejpeg().
heres my code:
$sourceUrl = $_FILES['path']['tmp_name'];
$thumbWidth = '100';
$thumbid = uniqid();
$img = imagecreatefromjpeg($sourceUrl);
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// output the image
imagejpeg($tmp_img);
// upload thumbnail to s3
$s3->putObjectFile($tmp_img, "mybucket", $thumbid, S3::ACL_PUBLIC_READ);
Firebug gives me this error :
illegal character
[Break on this error] (�����JFIF���������>CREATOR: g...(using IJG JPEG v62), default quality\n
If I modify imagejpeg this way,
imagejpeg($tmp_img, 'abc.jpg');
then I get the same error. :(
Can i get some help here please ?
If you check the documentation of imagejpeg you can see it outputs the image, it means the way you call it it gets sent to the browser. You can get it to save to a file the second way you call it - by passing a filename in the second parameter.
Also, $tmp_img is an image resource, not a ready-to-use image file.
I don't know how your upload function works, but: if you need the file contents to upload, do it like this:
ob_start();
imagejpeg($tmp_image);
$image_contents = ob_get_clean();
$s3->putObjectFile($image_contents, "mybucket", $thumbid, S3::ACL_PUBLIC_READ);
if you need a filename to upload:
$filename = tempnam(sys_get_temp_dir(), "foo");
imagejpeg($tmp_image, $filename);
$s3->putObjectFile($filename, "mybucket", $thumbid, S3::ACL_PUBLIC_READ);
You have to define the header:
header('Content-type: image/jpeg');
1) $tmp_img is a resource not a file. You probably need to save the image to disc and use that for putObjectFile
2) You probably need to tell S3 that the file you're uploading is of type image/jpeg
Well guys thank you very much again, I screwed around a bit more and combining that with your responses I got this working as follows :)
$thumbid .= ".jpg";
$img = imagecreatefromgif($sourceUrl);
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$path = '/var/www/1.4/wwwroot/cdn/'.$thumbid;
// output the image
if(imagegif($tmp_img, $path)){
$thumblink = "";
// upload thumbnail to s3
if($s3->putObjectFile($path, "mybucket", $thumbid, S3::ACL_PUBLIC_READ)){
$thumblink = "http://dtzhqabcdscm.cloudfront.net/".$thumbid;
imagedestroy($tmp_img);
}
return $thumblink;
}

Image resize issue in PHP - gd creates ugly resized images

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.

Categories