Our blog

 

PHP Save Images Using cURL

Some hosts disabled the ini setting allow_url_fopen. This also means that the ability to easily grab images by calling imagecreatefromjpeg($img) where $img is a url for an external image does not work.

This is a shame as this technique is pretty easy..

PHP:
  1. $remote_img = 'http://www.somwhere.com/images/image.jpg';
  2. $img = imagecreatefromjpeg($remote_img);
  3. $path = 'images/';
  4. imagejpeg($img, $path);

However I was tearing my hair out trying to get a product feed integration system to work on a host that has disabled the allow_url_fopen mechanism which meant the above wouldnt work.

Thankfully cURL was still working. So here is the function I made for grabbing and saving an image using cURL instead:

PHP:
  1. //Alternative Image Saving Using cURL seeing as allow_url_fopen is disabled - bummer
  2. function save_image($img,$fullpath){
  3.     $ch = curl_init ($img);
  4.     curl_setopt($ch, CURLOPT_HEADER, 0);
  5.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  6.     curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
  7.     $rawdata=curl_exec($ch);
  8.     curl_close ($ch);
  9.     if(file_exists($fullpath)){
  10.         unlink($fullpath);
  11.     }
  12.     $fp = fopen($fullpath,'x');
  13.     fwrite($fp, $rawdata);
  14.     fclose($fp);
  15. }

Another Problem Solved :-)

More Reading:

56 Comments

Niki
December 16th, 2008

Hi!

I have a problem with image downloading from Remote server, which sends headers:

image/jpeg for some images
and
binary/octet-stream for others

I would like to use curl to check once with remote server for content-type and accordingly redirect for image/jpeg or else download using curl to set correct image/jpeg header for binary data. Can you help?

Dear Admin! pls email me on email specified, txt only.

 

admin
December 16th, 2008

emailed you ;-)

 

Daniel Esobar
December 16th, 2008

can you please post how you did it?

 

admin
December 17th, 2008

not had an email from her yet...

I suspect though that the solution is to download whatever it is via curl and then check for a valid image once we have a local file to work on.

 

Niki
December 18th, 2008

Hi Joseph!

Thanks for replying.

Here are the images:

i.indiafm.com/stills/celebrities/sada/thumb1.jpg

AND

i.indiafm.com/stills/celebrities/sada/thumb5.jpg

See both image requests have different content-type headers.

I await a response from you asap.

Thanks
Niki

PS: I actually have somehow implemented something for the time being as you suspected...

 

admin
December 18th, 2008

This code is saving both images fine for me:

PHP:
  1.  
  2.  
  3. foreach($img as $i){
  4.     save_image($i)
  5.     if(getimagesize(basename($i))){
  6.         echo '<h3 style="color: green;">Image ' . basename($i) . ' Downloaded OK</h3>';
  7.     }else{
  8.         echo '<h3 style="color: red;">Image ' . basename($i) . ' Download Failed</h3>';
  9.     }
  10. }
  11.  
  12. //Alternative Image Saving Using cURL seeing as allow_url_fopen is disabled - bummer
  13. function save_image($img,$fullpath='basename'){
  14.     if($fullpath=='basename'){
  15.         $fullpath = basename($img);
  16.     }
  17.     $ch = curl_init ($img);
  18.     curl_setopt($ch, CURLOPT_HEADER, 0);
  19.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  20.     curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
  21.     $rawdata=curl_exec($ch);
  22.     curl_close ($ch);
  23.     if(file_exists($fullpath)){
  24.         unlink($fullpath);
  25.     }
  26.     $fp = fopen($fullpath,'x');
  27.     fwrite($fp, $rawdata);
  28.     fclose($fp);
  29. }

 

Litza
July 29th, 2009

Just wanted to say thanks - this worked like a charm and saved me lots of time!

 

nur
August 30th, 2009

this cURL example isn't working for me! it saves empty image file! what would be the reason? even appreciating for email.

 

acid
September 18th, 2009

Hi,

these scripts are working perfekt.
but i've got urls that are working as loadbalancers.
here is an example:
http://static.flickr.com/2610/3911380499_e747697efe.jpg
redirects you to
http://farm3.static.flickr.com/2610/3911380499_e747697efe.jpg

is there a way, to translate the url first, and then download the image?

hope you can help.

greetings

Philipp

 

admin
September 18th, 2009

try using adding

PHP:
  1. curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);

 

Web Developer Bangladesh
October 12th, 2009

WOW!!!! Great site with great HELP !!!

This tutorial helps me too much...

Thanks
Mehedi Hasan

 

Ed Cross
October 30th, 2009

I have a business card application and am trying to get 4 items created from file.drawtext2.php to be saved into 1 png image.
With your code I have all 4 images saving individually. Can you help?

 

Ed Cross
November 2nd, 2009

I mis-stated what I was trying to do. I am not using file.drawtext2.php anymore and am trying to get your code to save all images into 1 complete image. Do you know how I can do this?

 

admin
November 3rd, 2009

Hi Ed

thats beyond the scope of this blog post I'm afraid

 

Hussein
January 30th, 2010

Hi, this is a great thank you.

I am trying to save website screen shots locally so that I don't over use the free service offered by a third party.

Here is how the image urls look like:
http://open.thumbshots.org/image.pxf?url=http://www.example.com/whatever/

I would like to be able to save it with the domain name in the following format: domain.ext.jpg

I know how to extract the domain from the url but don't know where I need to change the name of the file before it is saved because currently it saves it with the last segment of the long url.

example:

url: http://www.example.com/dir/remotedir
is currently saved as: remotedir

url: http://www.example.com/dir/remotefile.php
is currently saved as: remotefile.php

I would like it to save the image in both cases above as: example.com.jpg

Thank you in advance.
Hussein

 

Pavel m.
February 9th, 2010

Thanks a lot or this help

 

Player911
February 18th, 2010

I keep failing to get this script to work. Right out of the gate I am getting undefined functions for $save_image().

 

KB
February 27th, 2010

try 2 things Player911. 1) Remove the $ from save_image and if that doesn't work, put the function above the line where you call

save_image(img,$fullpath);

 

Rab
May 13th, 2010

Help me out too - #3 in Google for the keyowrds I searched. Nice one admin, that's another one I owe you ;-)

 

admin
May 13th, 2010

lol :)

HTH

 

php answers
May 21st, 2010

Very well put together tutorial, well worth the read :)

thank you

 

Nick
July 7th, 2010

Nice tutorial.but it creates a problem when the image mime type will not retrieve.

You can find almost all help related to the open sources from,

http://phpschools.freehostia.com

 

Rombaut
September 26th, 2010

Hey,

This tut looks great but still I'm noob at this. However I was wondering: Is there a possibility to get specific information from a remote image like width, height.. etc.. using cURL?

Appreciate any suggestions.. Thank you!!

 

admin
October 12th, 2010

download the image and then use the getimagesize function

http://php.net/manual/en/function.getimagesize.php

 

TerMa
December 11th, 2010

this cURL example isn't working for me! it saves empty image file (Zero Size)! what would be the reason? even appreciating for email.

 

TerMa
December 11th, 2010

Upon further investigation, it appears that the problem of my curl is Error #6 = " Couldn't resolve host 'aHostName' " and I see somewhere "becuse the DNS resolution on the absolut Apache server is not working consistently" but I never get true result. what would be the reason? even appreciating for email.

 

steven
January 12th, 2011

thanks for your advice .. I had use curl to grab image from other website .. its working very well

 

Calvin Froedge
January 21st, 2011

Curl is awesome and you're da man. Thank you!

 

RJ
March 1st, 2011

Hello,

I'm having the same issue that others have had where a png file is created, but there's no actual image showing up. Here is my code:

$remote_img = 'http://chart.apis.google.com/chart?chxl=0:|Jan|Feb|Mar|Jun|Jul|Aug|1:|100|75|50|25|0&chxt=x,y&chs=300x150&cht=lc&chd=t:60.037,57.869,56.39,51.408,42.773,39.38,38.494,31.165,30.397,26.876,23.841,20.253,16.232,13.417,12.677,15.248,16.244,13.434,10.331,10.58,9.738,10.717,11.282,10.758,10.083,17.299,6.142,19.044,7.331,8.898,14.494,17.054,16.546,13.559,13.892,12.541,16.004,20.026,18.529,20.265,23.13,27.584,28.966,31.691,36.72,40.083,41.538,42.788,42.322,43.593,44.326,46.152,46.312,47.454&chg=25,25&chls=0.75,-1,-1';
$path = 'images/reports/test.png';

$ch = curl_init ($remote_img);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata = curl_exec($ch);

if(file_exists($path))
{
unlink($path);
}
$fp = fopen($path,'x');

curl_close ($ch);
fwrite($fp, $rawdata);
fclose($fp);

Any help would be appreciated. Thank you

 

Julio
March 22nd, 2011

What a great help, thx

 

Joseph
March 29th, 2011

Hi, great tutorial. Is there any way to tweak it in order to be able to change the name that the images is saved as? Also if possible to resize it?

 

Noel B
March 31st, 2011

I used the script to store images into server from remote sources but, however the image saved has zero bytes... Any clues to whats wrong? Thanks!

 

jaceksww
April 6th, 2011

You savet my life with that cURL saving :) thanks

 

waleed
April 21st, 2011

great script.
but what i cant do is, i am unable to save the images in this folder " gozanga\images\movie_poster" it saves in the base folder " gozanga\" no matter what i try to do, any pointers??

 

Kory
April 23rd, 2011

Any suggestions on how to have this script read the url from a database.

I need to harvest a large number of images, and the names are stored in my mysql db named jos151, table jos_vm_product, and field name product_full_image.

Thanks for your great posts.

 

Jamie Slater
April 28th, 2011

For all those having empty image issues; use chmod after you have cURLed one out.

... curl_close ($ch);
if(file_exists($fullpath)){
unlink($fullpath);
}
$fp = fopen($fullpath,'x');
fwrite($fp, $rawdata);
fclose($fp);

//This sets permissions on img making it viewable.

chmod($image_name,777);

 

Azirius
May 18th, 2011

This helped a lot with an Facebook avatar integration system that I needed to develop.

Sourcing off of Facebook's image server seemed to slow down page loads a fair chunk, so, having this system download a new one every 24 hours is a great way for me to keep down page loads.

 

Matthew
June 9th, 2011

How can you make this script work with an image url like the following:
http://shopping.netsuite.com/core/media/media.nl?id=1695&c=569110&h=e431a8edbd98b969d8a3

My images keep appearing to be 0kb in size.

My source code is the following:
// Download netsuite image
$ch = curl_init ($_POST['netsuite_image']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
$rawdata=curl_exec ($ch);
curl_close ($ch);

$netsuite_image = DIR_FS_CATALOG . DIR_WS_IMAGES . "netsuite_" . $_POST['netsuite_id'] . ".jpg";
$products_image = "netsuite_" . $_POST['netsuite_id'] . ".jpg";
$fh = fopen($netsuite_image, 'w') or die("can't open image file");
fwrite($fh, $new_image);
fclose($fh);

 

Matthew
June 9th, 2011

please disregard my last post, it was a simple error using the wrong variable name :)

 

carlos
July 29th, 2011

graciasssssssssssssssss me salvaron la vida solo me flataba
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);

 

Hari
August 21st, 2011

I wish to save files >300mb, the script work fine for images but not for heavy movie files.

Can u provide a example please.

 

Manish kumar
August 26th, 2011

@Admin your code works like charm. thanlks alot you save me time.

 

yas
September 29th, 2011

I'm using PHP cURL to fetch image from another website and insert it into my page. I was wondering if it is possible to have the fetched image cached on my server? For example, when a visitor requests a page, the image is fetched and cached on my server for 24 hours. The image is then entirely served locally for 24 hours. When the 24 hours expire, the image is again fetched and cached when another visitor requests it, in the same way.

 

Tấn Việt
November 2nd, 2011

This post is useful to me. Could I translate it into Vietnamese ?

 

Eduard
November 16th, 2011

Nice cURL script. Works fine but I wanted to add user authentication

I added:

curl_setopt($ch,CURLOPT_USERPWD,"$username:$password");

but that didn't work.
Any ideas?

 

gps
November 23rd, 2011

Hello,
I'm use your code to download image from remote but that didn't work for url that contain whitespace, please help

 

Rich
November 30th, 2011

Thanks heaps for this. It's a really handy bit of code. One question, if you have time...

It all seems to be working until I go to open the saved file. It's just a blank jpg. Any idea what I might be doing wrong?

 

Mike
January 11th, 2012

A combination of this and Simple HTML DOM Parser would probably be a good idea.

 

admin
January 11th, 2012

Not sure why, there is no DOM on an image

 

prabagar
February 11th, 2012

thanks

 

Sha
March 6th, 2012

Great! i used it to run thru a loop and downloaded all the users profile images. Thanks a LOT!

 

zhiyo
March 9th, 2012

I also get 0kb files... how do you fix this?

Here's my code:

$dir = str_replace('//','/',$dir);
$ext = substr($file_url,-3,3);
$new = $dir . md5($file_url) . "." . $ext;
if(file_exists($new)){
unlink($new);
}
$ch = curl_init($file_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
curl_close($ch);
$fp = fopen($new, 'w');
fwrite($fp, $data);
fclose($fp);

 

zhiyo
March 9th, 2012

Ok, found the problem... it works with http but not with https... do you have any clue how to skip that problem ? Configuration problem?

 

jayendra
March 29th, 2012

Nice tutorial. I hope it will solve my problem.

Thanks to share this.

 

Corey
April 10th, 2012

For HTTPS support, try adding the following:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

 

Mike Carter
May 1st, 2012

Gads, after reading all the "this script works perfectly" comments, I feel like an idiot. All I want to do is copy a file from one folder and put it in another: to copy the file 'tester.jpg' from images to images/test

Nothing copied. What am I leaving out?

Thanks -- Mike

 

 

Leave a Reply