PHP image on the fly resizing with caching, and croping.
Edit: July 1st 2009 1:46 AM
There is a new version of php image resize which now supports remote images, you can download it now or visit the github page here:
Visit PHP Image Resize (GitHub)
There is also a new example page included in the repository.
---------------------------------------------------------------------
Just thought I would share a recent function that we have built to resize images on the fly, so if you have an image that is 800x800, and you want to make a thumbnail to 200x200 just use the function like this:
<img src="<?php echo resize("PATH_TO_IMAGE",array("w"=>200,"h"=>200)); ?>" border="0" />
Be sure to check out the example page.
Configuring is pretty simple, just make sure the cache directory that you choose is writable by the server, and you should be up and running.
The script will compare the generated images timestamp to the original image's timestamp, so if the original image is changed all cached images will be re-built.
I hope you enjoy, and let us know if you have any questions, thanks!






























83 COMMENTS
Question. If an image has a transparent background like a .png, it receives a white one when it's resized. Is there any way to change the background color so that it matches the site better?
regards,
My original code is:
printf ("<a href='files/%s' target='_blank'><img src='files/%s' width='200' border='0'></a>", $myrow['pilt'], $myrow['pilt']);
I dont understand why can i made this code work width image resizer - i haw only error
First of all I get the following error messages:
Notice: Undefined index: h in C:\Users\paulatop\wamp\www\temp\resize.php on line 22
Notice: Undefined variable: h in C:\Users\paulatop\wamp\www\temp\resize.php on line 32
Notice: Undefined variable: h in C:\Users\paulatop\wamp\www\temp\resize.php on line 58
Notice: Undefined index: maxOnly in C:\Users\paulatop\wamp\www\temp\resize.php on line 83
I am able to remove the notices by using the suggestion from here: http://www.dmxzone.com/go?13811
I have configured the cache folder correctly, I echoed the $cacheFolder to be sure.
The thumbnails simply don't generate.
I've been testing this with wamp on vista and xp. Both have the same outcome.
Do I need a plugin such as ImageMagick to make this work?
Yes ImageMagick is required for this script. In some cases the 'convert' command path to ImageMagick may vary on different servers.
I installed ImageMagick and got the demo working. I've been playing around with it a bit and found a couple of things:
- Images with spaces in their names don't work. Maybe a str_replace can be used somewhere to fix this.
- on line 25 there is the following line of code:
$imgPath = str_replace('.'.$ext,'',$imagePath);
I can't find the variable $imgPath anywhere else, so not sure if it is needed?
- to find the maximum allowable height or width change the line:
if($width > $height){
to:
$widthPercentage = $width / $w;
$heightPercentage = $height / $h;
if($widthPercentage > $heightPercentage){
Hope these are constructive.
exec("convert ".$imagePath." -resize ".$resize." -quality ".$quality." ".$newPath);
To:
exec("convert \"$imagePath\" -resize ".$resize." -quality ".$quality." ".$newPath);
It run perfectly in my localhost testing but it didnt work online.
exec("convert ".$imagePath." -resize ".$resize." -quality ".$quality." ".$newPath);
Is it because this line of command only work in window but not linux??
The script is designed to use ImageMagick and PHP, if you have those two installed and working properly, check your cache folder's permissions. Let me know if your getting any kind of errors.
Speng,
You may want to check your online machine's path to convert. Try "whereis convert" and see if you can find convert in a different location.
Yup, I've actually got a new version of the script that supports external image requests then cache's the resized image locally. I'll be posting a version on github soon, i'll link to it here when its ready! Thanks for the interest in the script.
please tell me what is the mistake.
It could be a number of reasons, what kind of server environment are you running? Do you have ImageMagick running? Have you checked your cache folder's permissions? Make sure your site can write to your cache folder and be sure you have ImageMagick configured correctly.
Thanks
http://filmnagaram.com/resize/example.php
:( what may be the problem??
Finally an image resize script that works.
Now I only have one issue: can we have ZoomCrop?
I'd like to get rid of the black bars on the side when cropping, I want the image to fill out the entire dimensions I specify.
Like timthumb ;)
Oh, and another issue: I'm trying to get this done in WordPress. Since WP uses absolute links, this script interprets these as external links ... any idea how to avoid this duplication of images that already are on the server?
Look for
<b># check for remote image..</b>
Under this line you'll find a bit of code that checks the image url if it contains "http".
Ich changed this to
<b> if((ereg('http://',$imagePath) == true) && (ereg('http://www.mores.cc',$imagePath) == false) ):
<b>
For my domain, obviously.
After this check, add this to get rid of the absolute url and make it a relative url:
<b> if (ereg('http://www.mores.cc',$imagePath) == true):
$imagePath = ereg_replace('http://www.mores.cc', '', $imagePath);
endif;</b>
Now, how do I get zoomcrop :)
mores: Looks like you got this figured out, you could have just linked to the http://yoursite.com/image.jpg in the resizer var.
When it looks for an image it copies it over and caches it so it doesn't necessarily need to grab the external image everytime :) Save some bandwidth here and there
I haven't implemented it into wordpress before, but I imagine it is pretty similar to a standard php installation.
Find your global include file and include the function into the wordpress site. Then use the resize function to wrap your image src just like the documentation states, also make sure you have ImageMagick and your cache folder configured properly.
If you're extracting post images etc it'll be a bit complicated, too much so to post in this little box :)
Right now I'm using it in a wordpress installation that's running in a subdirectory and it fails - must be some path issue.
Hello, I installed your script and I think I'm doing something wrong, because I do not work either locally or remotely, have given permission (777) to the images directory. If you please take a look at http:www.mineralssalvat.com/example.php, I've also found that the image is seen in www.mineralssalvat.com / images / dog.jpg and this is correctamente.Tambien I enclose configuration www.mineralssalvat.com php / info.php.
Sorry but my English is very low
Greetings
had also trouble getting remote image too work. finally i discovered that jou just have to add s directory remote in the cache dir..
plz. explain what is imagemagic, what it does. also explain more about the folder/directories - cache?? convert??
i have a temp directory on my c: drive and the 'uploads' folder for storage.
and plz put full step by step inst. for us novice who can then make use of your work.
i need to resize my file ie. reduce it's file size when uploading and saving to my server? can this script do it?
help me and a coffee is coming up your way.
thanks.
then i had to poo
Thanks!
Andie
I'm sorry I haven't gotten back to some of the issues posted here. Imagemagick is a software suite that runs on the command line. It interfaces with php many other programming languages. More can be learned about imagemagick @ http://imagemagick.com.
Yes, to get remote images working, you will need to add a folder for remote images in your cache folder, there is a configuration for this in the function if you wish to place it elsewhere.
This script isn't meant to work when uploading the file, but rather when calling it inline on your code. It takes the originally sized photo and resizes it down. So you'd place the code in a 'View' or plain html / php file.
To save a new version of the photo, it should auto detect if the newer photo is "newer" than the cached one.. You can also clear out the cache folder to regenerate all you images again.
Thanks!
@arif - this is not a beginners script so if you have a project in mind and you'd like to use it, begin by reading about what ImageMagick is, and don't complain to the script provider for not having guided hand in hand.
First of all, this script is very good and it is working perfectly on my server.
But now i'm facing some troubles on it.
On my testing I made a new folder in the root directory and put all required files,folders & images inside it. Then I tested the URL like (www.mysite.com/demofolder), and it was perfect.
Then I tried to implement it on various images on the website itself. This time its showing 'Not found' images. My images are residing in different folders and subfolders but website have a master page, so each and every requests are passing tru index.php, so i made 'cache'(777) folder in the root directory where the index.php residing.
Can anybody help me where is the problem ? any directory structure issues ??
It sounds like your having some kind of path problem to your images. The best method is to use absolute paths to your webroot path.
/path/to/images/image.jpg
Something like that should work, just as long as your image is located at that absolute path.
Thanks
No luck with absolute path too.
Also I wondered by another behaviour.
As I told in previous post, its working perfectly in demo folder (ie; www.mysite.com/demofolder).
And then I put all files,folders & images in the root directory itself (ie; www.mysite.com/example.php).
Its showing only one image ( $settings = array('w'=>300,'h'=>300,'scale'=>true);)
and all others not appeared.
Do you know why?
For some strange reason, an external file can be written into the "external" directory, and convert seems to work since the script returns a file name that I can use, but that file does not exist.
I'm not sure where I can start looking for bugs. The directories are, apparently, writeable, and convert must be found or else I would not get a proper file name. Right?
I'm hosted at emerion and the directories are not CHMODable by me, but the tech guys tell me that php scripts can write anyways.
Any ideas?
I'd need to look at the code to see what exactly is happening. It still sounds like a path issue, maybe permissions? Can you post some code up on gist.github.com?
Hi Daniel,
Make sure those external directories that you are writing to are writeable by your webserver. In most cases that would be apache. If it is generating the md5 serial hash filename then things should be good, just sounds like a permissions issue. You might want to check your error logs for the site to find some kind of clues.
Thanks
thank you for getting back to me so quickly.
I don't have access to a lot of things on that host, I can't even use my FTP program's CHMOD function.
The host tech guys said "don't worry about it" and sure enough, a file has been generated in the cache/external directory. Which means that the directories *are* writeable by scripts.
But the files generated by convert are not, apparently.
Can this be?
You might want to make sure you have the correct path to convert. Depending on hosts, sometimes it will just be available as 'convert'.. Or you might need a full path to the function. '/usr/bin/convert'
There are definetely a few things that can go wrong due to configurations of server enviroments. No server is the same :)
I can take a quick look at your configuration / setup if you wanna send me some code.. Email it over to wes@joedesigns.com
Thanks
I don't think that an issue with path because one of the method is working fine (the scaling one) and the 'canvas-color' method not working.
I tried following code, there are 2 methods (scaling & canvas-color)
First I put this file in root directory itself (www/) there i can see
-First image(canavas-color method) - not showing
-Second image (scaling method) - showing fine
Then put it in another folder in root directory (www/testfolder/) there both images are fine.
So it seems that 'canvas-color' method have some issue when it is in root directory, actually that is what i looking for.
any clues?
==================================================================
<?php
include 'function.resize.php';
$settings1 = array('w'=>115,'h'=>60,'canvas-color'=>'#FFFFFF'); ?>
<img src='<?php echo resize('logos/8.jpg',$settings1)?>' border='1' />
<?php $settings2 = array('w'=>115,'h'=>60,'scale'=>true); ?>
<img src='<?php echo resize('logos/8.jpg',$settings2)?>' border='1' />
=================================================================
thanks for the script!.
i would like to request a copy of the external image source - resize - cache - use local image copy. i noticed on one comment that is now ready.
thanks in advance.
i would be following this post. :) subscribe to comments plugin is also a convenient feature. :)
I had to modify a section of code because if you crop an image with the width and height not being equal, you'd sometimes get the canvas instead of a proper crop.
I had to add this to the cropping section:
if (($h/$height)*$width>=$w) $resize = ($h/$height)*$width;
else if (($w/$width)*$height>=$h) $resize = "x".($w/$width)*$height;
Wes please confirm this is accurate...
$cacheFolder is from the document root of your server.
So is the url of the image itself, only the script checks this for you, not for $cacheFolder though, you need to specify this literally, so if your image is here: mystime.com/img/image.jpg, then this is your literal path: $_SERVER['DOCUMENT_ROOT']."/img/image.jpg".
$path_to_convert , as reported above is very different on many servers. If you dont have direct access to your account you can do the following in php, assuming 2 things: Image magick is in fact installed somewhere, and you do have eval() rights turned on...
try this in php:
eval('whereis convert', $output); echo var_dump($output))
This was the only way for me to confirm I had the right path to the imagemagick libs.
I am using xampp.
how did I know my cache folder and path to convert?
Thanks
I am trying to get this to work with the image url populated from database info, i.e
<img src="<?=resize($linkdir . $uploadfile_bground, $resize_settings)?>" alt="" />
This doesn't seem to work, however works fine when hardcoding the image url into it as in below...
<img src="<?=resize('/uploads/image1.jpg', $resize_settings)?>" alt="" />
Im sure theres something I'm missing, but can't find what
u might want to concat the variables prior to sticking them in the argument.. ex:
$filepath = $linkdir.$uploadfile_bground;
also debug that variable to see if its the correct path to your files. otherwise it should work
Thanks.
I have tried that, and although something is now happening, I don't know that this has been the cause.
What I am now seeing is that certain images are being resized and will show on the page, whilst others arent.
I am getting a cacheed image location load into the src for the image, but there isnt anything actually within the cache folder for that image.
Its odd as it does work with some images.
I have tried various image types, but that doesnt appear to be the cause, as it is working for each image type, just randomly.
Any ideas?
THanks again
Are all the images the same size relatively? same dpi at least? Its possible ImageMagick might be choking if the images are too large.
You should see temp images building into your cache folder. If you don't see any images added into your cache folder then you might be experiencing another problem. I'd need to see more code examples to help much further..
Got it sorted, well no idea how I did, it just seemed to work. Perhaps it was as you say something to do with the size of the images, as some of them were 6m!!
I have just limited the size the gallery will take during the upload, which will prevent this.
I have another issue now however, I am trying to deploy this onto a wamp machine (2003). I've got imagemagick installed, but seem to be having issues determining the path to convert...
I have: C:\Program Files\ImageMagick-6.6.2-Q16\convert.exe
however am getting the error below when trying to load my page.... (Incidentally this worked 100% on my linux test box).
PHP Warning: exec(): Unable to fork [C:\Program Files\ImageMagick-6.6.2-Q16\convert.exe 'uploads/7-DSC02203.JPG' -resize 80 -size 80x50 xc:transparent swap -gravity center -composite -quality 100 cache/d41d8cd98f00b204e9800998ecf8427e_w80_h50_cp.JPG] in C:\Inetpub\Websites\intertech\www\Scripts\function.resize.php on line 107
Solved this one, I had the path to imagemagick right, however if on windows you need to give IIS permission to execute scripts using the cmd shell.
To do this open up a cmd window (Start>Run>cmd) and enter the following command (You can copy and paste.....
cacls %COMSPEC% /E /G %COMPUTERNAME%\IUSR_%COMPUTERNAME%:R
Hope that helps someone :)
It does not work. Maybe it is because there is no .jpg? o .gif extension?
Yes, thats probably the problem your having, you should have the extension in your filename.
I am using your script, but when i resize, sometimes images are not resized proper. I can only see a part of the image..
url: http://www.pc-teros.es/carrusel/example.php
y en caso real me sale este error: "Cannot redeclare resize() (previously declared in /homepages/4/d284870012/htdocs/pc-teros/carrusel/function.resize.php:9) in /homepages/4/d284870012/htdocs/pc-teros/carrusel/function.resize.php on line 120"
url: http://www.pc-teros.es/carrusel/carru.php
¿me pueden ayudar?
Can't wait to try it.
Some images are correct but then some are not resized correctly
everything is solved. and is working perfectly here:
http://www.pc-teros.es/carrusel.php
example: http://www.pc-teros.es/carrusel/cache/a19e345bb85dc61a10e1bb2dc0fd1400_h128.jpg
thank you very much for the script.
if(isset($opts['scale']) && $opts['scale'] == true){
exec($path_to_convert." ".$imagePath." -resize ".$resize." -quality ".$quality." ".$newPath);
}else{
exec($path_to_convert." ".$imagePath." -resize ".$resize." -size ".$w."x".$h." xc:".(isset($opts['canvas-color'])?$opts['canvas-color']:"transparent")." swap -gravity center -composite -quality ".$quality." ".$newPath);
}
}elseif(!empty($w)){
exec($path_to_convert." ".$imagePath." -thumbnail ".$w."".(isset($opts['maxOnly']) && $opts['maxOnly'] == true ? "\>" : "")." -quality ".$quality." ".$newPath);
}elseif(!empty($h)){
exec($path_to_convert." ".$imagePath." -thumbnail x".$h."".(isset($opts['maxOnly']) && $opts['maxOnly'] == true ? "\>" : "")." -quality ".$quality." ".$newPath);
}
or system might work depending on your server.
rather than
exec($path_to_...
use
system($path_to_...
or
passthru($path_to_...
true: http://www.total-soft.net/Carrusel/carru.php
Example: http://www.total-soft.net/Carrusel/example.php
know any script to do the same as this, but only using the GD library functions.
thanks for your help and your time.
If I resize the picture to 240*160 it cuts out the center part of the picture. What if I want to resize but keep total picture?
You should be able to use crop=>false,scale=>true..
I believe that will solve your problems.
Just a question: is possible add a watermark to images after they are resized?
Thank you
Hi wes using scale does not fix it because then it only resizes from one side. What I want is a complete picture resized to the proportion needed and add whitespace if needed, hope this makes sense to you?
You can add watermarking into this script fairly easily.. Check this out:
http://gist.github.com/540817
You might need to tweak folder paths and such..
Hey Thomas,
If you take a look at the demo page, it has the same example your looking for.
I believe you'll want to only define width and height for your resize.. This will resize and add canvas space around the image.. you can also define the canvas-color.. If your using png's I think the canvas should be transparent by default
To return the favor...
@Thomas (and @wes, if you accept the suggestion or if you have improvements to do ...I'm just a poor web designer...).
Like Thomas I wanted to resize images but keep total picture, so I changed this part of your script:
I hope that this will be helpful, or at least not without a sense ;-)
On my site, I link pictures from external sites. A lot of the time, the end file names are similar (such as 01.jpg, etc.)
The function seemed to cache the remote image, and use that image over and over, regardless of the file path before the end file name.
To fix that, replace:
list($filename) = explode('?',$finfo['basename']);
$local_filepath = $remoteFolder.$filename;
with:
list($filename) = explode('?',$finfo['basename']);
$file_temp_add = str_replace('/', '_', $finfo['dirname']);
$filename = $file_temp_add."_".$filename;
$local_filepath = $remoteFolder.$filename;
Not a great fix, as it makes the cached file names look crazily unorganized, but your images will now all show if they are using the same file name! :)
ADD YOUR COMMENT