PHP Imagecreate & Different File Types
22 Jan 2008For a recent little bit of PHP scripting, I wanted to grab an image off of a remote server (not for any nefarious purpose!) and manipulate it in PHP (with GD). The actual manipulation was trivial, all I wanted to do was reduce the dimensions of the remote image, so I won’t go into that in this post.
However, when thinking about getting the remote file and making it a GD image
there were a few options available. The ‘normal’ methods of creating GD
images from files seemed like a reasonable start:
imagecreatefromfiletype, where filetype is one of png, jpeg, gif
(or even gd2, wbmp, xbm, xpm…). At first glance everything seems cool,
these functions can even grab the file from remote servers. Assuming
http://example.org/photo.jpg is a valid image, then the following
would work fine (if allow_url_fopen
is enabled in php.ini).
imagecreatefromjpeg('http://example.org/photo.jpg');
First Hurdle
The first problem that came to light was that I never really knew what kind
of image would be returned from the remote server. All of the remote image
names were something.gif but the actual image could be anything from a gif
to jpeg to png (the most common web image types). Determining the image type
isn’t particularly trivial, you can easily grab the MIME type from the remote
server and use the appropriate imagecreatefrom...
function but there’s no
guaranteeing that the server would necessarily throw out the correct MIME
(from testing, this didn’t appear to be a problem but one must always assume
that the MIME can be telling fibs).
I could have ploughed ahead, assuming everything was all ok and grab the
remote image in a switch
statement (or series of if
s, etc.) like so:
$remote_file = 'http://www.talkphp.com/avatars/salathe.gif';
$headers = get_headers($remote_file, 1);
switch ($headers['Content-Type'])
{
case 'image/jpeg':
$image = imagecreatefromjpeg($remote_file);
break;
case 'image/gif':
$image = imagecreatefromgif($remote_file);
break;
case 'image/png':
$image = imagecreatefrompng($remote_file);
break;
default:
die('Invalid image type');
}
Now, that’s a huge mess and whilst things could easily be tidied up by using variable functions or some other structure like that but the problem would still exist of looking at the mime type to determine which function to use. Wouldn’t it be great if there was a function which would create an image regardless of the image type fed into it? Worry not, such a function exists (but strangely isn’t discussed very often).
Introducing Imagecreatefromstring()
Grabbing the remote image from the server is really easy using
file_get_contents()
(or even cURL if you like). Once you have the
file’s raw contents, those can be fed directly into imagecreatefromstring()
and the function will return a nice, new GD image. Easy peasy!
If you want to be really, really concise (forgetting error handling, etc. for a moment) it’s a simple one-liner:
$image = imagecreatefromstring(file_get_contents('http://www.talkphp.com/avatars/salathe.gif'));
How cool is that? No need for ugly MIME type checking and calling different
functions based on that; the imagecreatefromstring()
function can autodetect
JPEG, PNG, GIF, WBMP, and GD2 images (so long as your PHP build supports
whichever type) without any hassle.
A final note, there are comments around regarding the memory consumption of
imagecreatefromstring()
and I have to admit that I’ve really not tested that
side of things at all. I like to use a lot of caching on my side of things
anyway, so the number of times that imagecreatefromstring()
is being called
in the script I mentioned at the beginning of this post is very infrequent: in
the region of once every couple of days! The main point here was to offer up
an alternative solution, which may or may not be useful to you at some point.