PHP: How to Download a Remote Image using GD or cURL
Posted on January 5, 2009, Filled under PHP,
Bookmark it
This a PHP Class useful if you need to download images from a remote location. You can choose between 2 methods to retrieve the image: using GD or cURL.
Here is the class (I will explain you how it works below):
<?php
class GetImage {
var $source;
var $save_to;
var $set_extension;
var $quality;
function download($method = 'curl') // default method: cURL
{
$info = @GetImageSize($this->source);
$mime = $info['mime'];
// What sort of image?
$type = substr(strrchr($mime, '/'), 1);
switch ($type)
{
case 'jpeg':
$image_create_func = 'ImageCreateFromJPEG';
$image_save_func = 'ImageJPEG';
$new_image_ext = 'jpg';
// Best Quality: 100
$quality = isSet($this->quality) ? $this->quality : 100;
break;
case 'png':
$image_create_func = 'ImageCreateFromPNG';
$image_save_func = 'ImagePNG';
$new_image_ext = 'png';
// Compression Level: from 0 (no compression) to 9
$quality = isSet($this->quality) ? $this->quality : 0;
break;
case 'bmp':
$image_create_func = 'ImageCreateFromBMP';
$image_save_func = 'ImageBMP';
$new_image_ext = 'bmp';
break;
case 'gif':
$image_create_func = 'ImageCreateFromGIF';
$image_save_func = 'ImageGIF';
$new_image_ext = 'gif';
break;
case 'vnd.wap.wbmp':
$image_create_func = 'ImageCreateFromWBMP';
$image_save_func = 'ImageWBMP';
$new_image_ext = 'bmp';
break;
case 'xbm':
$image_create_func = 'ImageCreateFromXBM';
$image_save_func = 'ImageXBM';
$new_image_ext = 'xbm';
break;
default:
$image_create_func = 'ImageCreateFromJPEG';
$image_save_func = 'ImageJPEG';
$new_image_ext = 'jpg';
}
if(isSet($this->set_extension))
{
$ext = strrchr($this->source, ".");
$strlen = strlen($ext);
$new_name = basename(substr($this->source, 0, -$strlen)).'.'.$new_image_ext;
}
else
{
$new_name = basename($this->source);
}
$save_to = $this->save_to.$new_name;
if($method == 'curl')
{
$save_image = $this->LoadImageCURL($save_to);
}
elseif($method == 'gd')
{
$img = $image_create_func($this->source);
if(isSet($quality))
{
$save_image = $image_save_func($img, $save_to, $quality);
}
else
{
$save_image = $image_save_func($img, $save_to);
}
}
return $save_image;
}
function LoadImageCURL($save_to)
{
$ch = curl_init($this->source);
$fp = fopen($save_to, "wb");
// set URL and other appropriate options
$options = array(CURLOPT_FILE => $fp,
CURLOPT_HEADER => 0,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_TIMEOUT => 60); // 1 minute timeout (should be enough)
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
fclose($fp);
}
}
?>How it works?
After initializing the class and the necessary variables are set, download() is called. Here the GetImageSize() function is used to obtain information regarding the image. We are interested in the mime-type from which he have to extract the type of image. Based on $type we will set some variables such: $image_create_func, $image_save_func, $new_image_ext (useful if $set_extension is set to ‘true’) and even $quality for ‘JPEG’ and ‘PNG’. The first 2 variables are needed in case we will use GD to download the image.
If $this->set_extension is not set, the saved image will have exactly the same name and extension (if any) as the remote image. If it is set, then we add $new_image_ext to the file name (could be the same as the remote one):
if(isSet($this->set_extension))
{
$ext = strrchr($this->source, ".");
$strlen = strlen($ext);
$new_name = basename(substr($this->source, 0, -$strlen)).'.'.$new_image_ext;
}
else
{
$new_name = basename($this->source);
}Set the full path where the image will be saved (filename + save folder):
$save_to = $this->save_to.$new_name;
Now, some functions would be called based on the $method value (could be ‘gd or ‘curl’):
if($method == 'curl')
{
$save_image = $this->LoadImageCURL($save_to);
}
elseif($method == 'gd')
{
$img = $image_create_func($this->source);
if(isSet($quality))
{
$save_image = $image_save_func($img, $save_to, $quality);
}
else
{
$save_image = $image_save_func($img, $save_to);
}
}If we choose ‘gd’ the LoadImageCURL() function will be called with one argument, $save_to, representing the full path where the image would be saved.
The curl_unit() is called with the ‘url’ argument ($this->source). The session is initialized and returns a cURL handle for use with curl_setopt_array(), curl_exec() and curl_close() functions. The next thing to do is to open the remote image for writing using fopen():
$ch = curl_init($this->source); $fp = fopen($save_to, "wb");
The function curl_setopt_array() sets multiple options for a cURL transfer without repetitively calling curl_setopt():
// set URL and other appropriate options
$options = array(CURLOPT_FILE => $fp,
CURLOPT_HEADER => 0,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_TIMEOUT => 60); // 1 minute timeout (should be enough)
curl_setopt_array($ch, $options);Now we need to grab the URL and pass it to the browser:
curl_exec($ch);
The last things to do is closing both the cURL resource (to free up system resources) and the open file pointer:
curl_close($ch); fclose($fp);
The image is now saved in the specified folder.
Now, let’s see how we can download the image using the ‘gd’ method! We’ll call the function needed to create the image from URL ($image_create_func). It’s used to return an image identifier representing the image obtained from the given URL:
// possible values: ImageCreateFromJPEG, ImageCreateFromPNG etc. $img = $image_create_func($this->source);
The next function used ($image_save_func) is used to create the image from the given image ($img). Another aspect here is the $quality variable. For JPEG images, the value ranges from 0 (worst quality, smaller file) to 100 (best quality). The default is the default IJG quality value (about 75). As for the PNG images, the range is from 0 (no compression) to 9.
if(isSet($quality))
{
// possible values: ImageJPEG, ImagePNG etc.
$save_image = $image_save_func($img, $save_to, $quality);
}
else
{
$save_image = $image_save_func($img, $save_to);
}Here’s an example of how you can use this class:
<?php
include_once 'class.get.image.php';
// initialize the class
$image = new GetImage;
$image->source = 'http://l.yimg.com/a/i/ww/beta/y3.gif';
$image->save_to = 'images/'; // with trailing slash at the end
$get = $image->download('gd'); // using GD
if($get)
{
echo 'The image has been saved.';
}
?>NOTE: Make sure the folder where the image will be saved is writable (chmod 0777).
Happy coding!
Do you wish to receive the latest updates as soon as they are posted? Get our RSS Feed or Subscribe to the Newsletter!
- January 5, 2009
- article by Gabriel C.
- 19 comments
Related Posts
PHP: How to Create Mirror Images using GDat January 19, 2009
PHP: Cropping a Rectangle Image to Square using GDat October 1, 2008 with 4 comments
Resize an Image (on the fly) & Keep its Aspect Ratio using PHP and GDat September 28, 2008 with 29 comments
PHP: How to Add Transparency to an Image using GDat October 13, 2008 with 6 comments
PHP: Practical cURL functionat September 2, 2008 with 1 comment


19 Replies to "PHP: How to Download a Remote Image using GD or cURL"
January 30, 2009 at 5:13 AM
Great! Excellent piece of code. I was going to write it myself but this saves al lot of time.
February 26, 2009 at 1:57 AM
i get “Could not obtain mime-type information. Make sure that the remote file is actually a valid image” error always.
February 26, 2009 at 11:06 AM
This error appears only if the remote file hasn’t a valid image mime type or a connection to that image cannot be made. What is the address of the image that you are trying to download?
March 1, 2009 at 2:23 AM
guess what? i think the error was in the variable i was passing to the function, if it had an space (the image path) it couldn’t be downloaded, so, i used str_replace(‘ ‘, ‘%20′, $imageURL) and it worked.
i did a very nice osC database leecher, even with images.
thanks to you!
March 30, 2009 at 10:13 PM
class works great! thanks.
April 15, 2009 at 8:03 PM
First off, tx for the class.
Secondly, i have a bit of a problem/question
I have altered your class a tiny bit
if(isSet($this->givenName)) {
$new_name = $this->givenName.’.’.$new_image_ext;
}
if(!isSet($this->givenName)) {
if(isSet($this->set_extension))
{
…
}
so ik can use a customize name.
When i hardcod the name it works like
$image = new GetImage;
// just an image URL
$image->source = ‘http://img.dailymail.co.uk/i/pix/2007/12_01/17banksyES_468x606.jpg’;
$image->givenName = “testing”;
but when i set it dynamic it doesn’t work anymore, like
$image = new GetImage;
// just an image URL
$image->source = ‘http://img.dailymail.co.uk/i/pix/2007/12_01/17banksyES_468x606.jpg’;
$test = $merchantName.’-’.$this->id;
$image->givenName = $test;
The problem is i don’t get the file with an extension?
regards
May 5, 2009 at 11:25 PM
cool, I plan to write something like this, so nice one.
July 15, 2009 at 11:04 PM
Gabriel,
I have a few questions about use of this for a non-profit moving images from hosting. If you would please email me – I am unable to find an email address for you.
July 30, 2009 at 5:26 PM
Call to undefined function curl_init()
what wrong?
by the way, i using php5
July 30, 2009 at 5:31 PM
You do not have the cURL library enabled/installed. Check these URLs: http://www.php.net/manual/en/curl.setup.php and http://www.php.net/manual/en/curl.installation.php (especially the comments).
July 30, 2009 at 5:33 PM
john, are you sure you have enabled curl in php.ini ?
July 30, 2009 at 10:18 PM
Just want to point out that by using
@GetImageSize(), this class will automatically fail on websites that require you to fake the referer before downloading an image. Perhaps the next version could use cURL to determine the MIME type and allow for passing cURL OPTS to the function. Thanks for the awesome start though.October 15, 2009 at 7:35 PM
thanks a lot….
November 14, 2009 at 8:33 AM
GREAT! but, how can i get the path to image in their new folder?
can u help me with this?
January 8, 2010 at 3:52 PM
Thank you very much! this script is awesome!!!
just need to combination with another GD script to rename the file, automatic create thumbnail and also automatic create folder based on the image category…
February 8, 2010 at 9:28 AM
Hi,
I need to pull down some images that work fine via a browser but when using code like this or even WGET, I get ‘connection refused’. Any ideas on how to get these images?
Cheers.
May 27, 2010 at 7:15 AM
I also get ‘connection refused’ with getimagesize and can’t find a solution anywhere.
June 22, 2010 at 2:39 PM
code works great! thanks.
July 13, 2010 at 6:16 AM
Gabriel, the code works great. However, I was wondering how I would go about overwriting an image rather than saving a new one.. Didn’t see any options for that in the class.
Thanks,
Arthur