The web nowadays requires a level of interactivity never seen before. People love commenting and building communities, and a huge part of that is putting a face to your online presence. To this effect there is a big demand for image processing techniques using web based languages. My web language of choice is PHP and so here is a short walkthrough, including code, on how to create a picture resizing function.
This function can both keep the aspect ratio of the picture, or force the picture to fit the new dimensions. It is designed for jpeg pictures but can easily be extended to cater for gif and png.
The first thing you need to do is create your form in your web page. This basically requires you to set a flag in the form tag like so:
<form name="myForm" action="uploadpic.php" method="post" enctype="multipart/form-data" />
The enctype flag basically tells the browser to break the form objects down and send in chunks. This is transparent to the user, and to the PHP script receiving the data. But is useful to know.
You will then need a form element with type "File" which will give you the typical input box with a browse button to allow your users to search for the file they want to upload.
<input name="userfile" type="file" size="40" />
Now we need a PHP file to receive the file, we are assuming you have a file called uploadpic.php, within your form handling code you should have something like this to call the function we are about to write:
if (@is_uploaded_file($_FILES["userfile"]["tmp_name"]))
{
$img_name = resizePic("player","userfile","../picupload/",150,150,0,"destination_name.jpg");
}
$_FILES is a server variable containing an array of the uploaded files, note that "userfile" is the name of the form element we specified earlier, the tmp_name is the temporary name given to the object when its uploaded. The first line basically confirms the file was uploaded ok. The second line calls our function resizePic and stores the contents into a variable called $img_name. The return value of the function is discussed later.
OK now onto our function definition, we saw the variables passed to it in the previous section of code, now we can see what each parameter does.
function uploadPic($prefix,$formSrc,$dDir,$maxWidth,$maxHeight,$resizeFlag,$tempName) ;
- The $prefix parameter defines the prefix for all images uploaded, if left blank no prefix is given. This is so we could have all our images renamed to news_00001.jpg etc.
- The $formSrc parameter simply passes the name of our form element to the function, so it can find the file we uploaded.
- $dDir is the destination directory for the image
- $maxWidth is obviously the maximum width the picture can have
- $maxHeight performs similarily
- $resizeFlag defines whether the image should keep its original aspect ratio
- And finally $tempName defines the name of the image
if (!copy($_FILES[$formSrc]["tmp_name"],$dDir.$_FILES[$formSrc]["name"])) {
print ("failed to copy $file...
\n");
}
This code will copy the file, with its current file name, to our destination folder.
If no $tempName was given we want to create a random name for the image, we do this simply by concatonating the prefix and a random number like so:
if ($tempName == "") { $tempName = $prefix."_".mt_rand().".jpg"; }
Next we need to create a few variables to store the location and names of our source image, and the eventual location of our finished image.
//hard copy of picture
$src_img = $dDir.$_FILES[$formSrc]["name"];
//destination
$dest = $dDir.$tempName;
We now need to get a little information about our file, confirm its an image, and find out its current dimensions. This is done easily with a function call to one of the PHP GD APIs.
//get source dimentions
$src_dims = getImageSize($src_img);
Now we have our image information we need to then create a temporary image in memory and deal with each image type seperately, for the sake of this tutorial I am simply going to concentrate on jpeg only, the case statements for other types are left in though and it will only take a small amount of work to alter the function to work with all image types.
//create appropriate temp image
switch ($src_dims[2]) {
case 1: //GIF
break;
case 2: //JPEG
$srcImage = imageCreateFromJpeg($src_img);
break;
case 3: //PNG
break;
default:
return false;
break;
}
Next we need to find out if we want to keep the aspect ratio, if so resize using a divisor, else just force the image to the correct dimensions. This is done by finding out how the image dimensions compare to our desired dimensions then dividing or multiplying accordingly.
$srcRatio = $src_dims[0]/$src_dims[1]; // width/height ratio
$destRatio = $maxWidth/$maxHeight;
if ($destRatio > $srcRatio) {
$destSize[1] = $maxHeight;
$destSize[0] = $maxHeight*$srcRatio;
}
else {
$destSize[0] = $maxWidth;
$destSize[1] = $maxWidth/$srcRatio;
}
//if set image dimensions are required:
if ($resizeFlag == 1) {
$destSize[0] = $maxWidth;
$destSize[1] = $maxHeight;
}
As you can see we now have an array called $destSize which contains the final height and width of our image. All we have to do now is create a new image in memory to the correct dimensions, then copy our source image into that new placeholder. We will use a function called imageCopyResampled to achieve this which usually gives the best results when resizing.
$thumb_w = $destSize[0];
$thumb_h = $destSize[1];
$dst_img = imageCreateTrueColor($thumb_w,$thumb_h);
imageCopyResampled($dst_img,$srcImage,0,0,0,0,$thumb_w,$thumb_h,$src_dims[0],$src_dims[1]);
Our image is almost done, all we need to do now is save our image to the destination folder and delete any temporary images we created along the way. We then return with our final image name so that the calling function knows the exact name of the image.
switch ($src_dims[2]) {
case 1:
break;
case 2:
imageJpeg($dst_img, $dest, 75); //75 denotes image quality / compression ratio
break;
case 3:
break;
}
//$y++;
unlink($src_img);
return $tempName;
And that is it, you now have a function capable of resizing uploaded images, if you are a basic user this will suit your needs perfectly well. However if you will be doing a vast number of resizes then this code may be slightly slow for your needs and it may well be worth looking into other resize methods that give lower accuracy.
On a final note with regards to performance it is generally much better to resize on upload rather than dynamically when a page is generated. It is a trade off between space and processing time, but if your site is popular then dynamically create each image on the fly can cost a lot in processing time and make your site slow.

17 comments:
Sweet as a nut m8! Great work!
A couple of gotchas to be aware of, in addition to all the problems with permissions:
1. PHP normally has a maximum uploaded file size setting of 2Mb, so you may not be able to upload files above this size.
2. PHP normally has a maximum memory-per-script setting of 8Mb. Much more memory is required to create an image (as per imageCreateFromJpeg) than the image size on disk. Depending on the compression etc, the ratio of memory to disk size can vary from 1:1 to 20+:1.
If your script just fails silently with no error message when it gets to the imageCreateFromJpeg statement, you have almost certainly run into this memory limit - something you can do with a file size of only 200Kb.
I've designed similar systems in the past and I've found that in the context of image galleries, generating the images dynamically but then caching them for future use is the way to go. That way it doesn't slow down uploading images and you still only have to generate the image once - the first time a specific size of that image is requested. This also allows you to change the variety of sizes of pictures on the fly - without any expensive bulk resize operations.
how about transparent PNGs?
go to this address: http://stefangabos.blogspot.com/2006/10/zebra-php-framework-php-image.html and you'll have a PHP class I made exactly for this. And also handles transparent PNG's :)
It should be noted that image editing in PHP requires the GD library. Which is of little consequence as it is usually bundled with PHP. However, if you manually install the library it will lack some features.
Cristian George, transparent PNG's are handled in a similar way as JPEGs by PHP.
Instead of:
case 3: //PNG
break;
Replace it with:
case 3:$srcImage = imagecreatefrompng($src_img);imagesavealpha($srcImage,true) ;break;
Then, when you see (further down in the script):
case 3:
break;
Replace it with:
case 3:imagepng($dst_img, $dest)break;
That should just about do it. PHP handles alpha in PNG's quite oddly though, but hopefully nothing will go wrong.
It's also important to note that you define a function named uploadPic yet you call a function named resizePic. Not a big deal. You also neglect the fact that the function you define should be surrounded by curly braces.
Very true angela, apologies there.
The curly braces were omitted simply because I only specified a prototype of the function and not the code in one entire block.
The function names are a typo!
Ill correct it
Thanks
Where is the code??? Do I have to copy-paste all those quoted snippets? Isnt there a single file with an overview of the whole code??
I'm thinking the same thing...where is the code?
Its a good tutorial, but quite confusing because of diff. function names etc. It would be nice to have a file with the finished code...
hey thanks for the tutorial. What about validating the images to see if they are images. One way you can do that is chck the resolution on them using GD2 lib. if they are massively huge then it not a image.
PHP Tutorials
This was very helpful as I've been researching this for some time though. This is a very good tutorial on using PHP to resize images and for uploading images as well. Thanks for for sharing your thoughts, insights and experience!
Instead of doing all this CPU-intensive image manipulation on your webserver, you can easily offload it to a remote service like SteadyOffload. The interface to the service is fairly simplistic - you use a custom HTML attribute called “xmanip” and a few image instruction mnemonics. The rest of the stuff is done automatically - manipulation, caching and delivery:
http://steadyoffload.com/thumbnail-problem
Try it. The benefits over having a PHP thumbnail script are numerous.
Hi there, I'm a bit of newb here so would really appreciate any feedback.
I have copied all the code into a text editor.
I have set up a folder on my server called /gallery which i would like to upload images to that change to 550px wide.
I have also set up a folder on my server called /gallery/thumbs which i would like to upload images to that change to 128px wide for landscape and 96px wide for portrait.
Question: in the code where do I set these folder and pixel variables. Do I change all the $dDir to $/gallery
Thanks - for your time
Visitors would appreciate it more if the full source code is made available. Not everyone can put the pieces of the puzzle together correctly.
your blog is very useful. I have a blog on PHP called PHP Coach .Please visit the same and let me know your opinions
To learn php,html,javascript,ajax,mysql,jquery with advanced concepts, you can visit http://advancedphptutorial.blogspot.com
Post a Comment