I need to save an image from a PHP URL to my PC.
Let's say I have a page, http://example.com/image.php
, holding a single "flower" image, nothing else. How can I save this image from the URL with a new name (using PHP)?
12 Answers
If you have allow_url_fopen
set to true
:
$url = 'http://example.com/image.php';
$img = '/my/folder/flower.gif';
file_put_contents($img, file_get_contents($url));
Else use cURL:
$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
Here you go, the example saves the remote image to image.jpg.
function save_image($inPath,$outPath)
{ //Download images from remote server
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
save_image('http://www.someimagesite.com/img.jpg','image.jpg');
Vartec's answer with cURL didn't work for me. It did, with a slight improvement due to my specific problem.
e.g.,
When there is a redirect on the server (like when you are trying to save the facebook profile image) you will need following option set:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
The full solution becomes:
$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
I wasn't able to get any of the other solutions to work, but I was able to use wget:
$tempDir = '/download/file/here';
$finalDir = '/keep/file/here';
$imageUrl = 'http://www.example.com/image.jpg';
exec("cd $tempDir && wget --quiet $imageUrl");
if (!file_exists("$tempDir/image.jpg")) {
throw new Exception('Failed while trying to download image');
}
if (rename("$tempDir/image.jpg", "$finalDir/new-image-name.jpg") === false) {
throw new Exception('Failed while trying to move image file from temp dir to final dir');
}
See file()
PHP Manual:
$url = 'http://mixednews.ru/wp-content/uploads/2011/10/0ed9320413f3ba172471860e77b15587.jpg';
$img = 'miki.png';
$file = file($url);
$result = file_put_contents($img, $file)
None of the answers here mention the fact that a URL image can be compressed (gzip), and none of them work in this case.
There are two solutions that can get you around this:
The first is to use the cURL method and set the curl_setopt CURLOPT_ENCODING, ''
:
// ... image validation ...
// Handle compression & redirection automatically
$ch = curl_init($image_url);
$fp = fopen($dest_path, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
// Exclude header data
curl_setopt($ch, CURLOPT_HEADER, 0);
// Follow redirected location
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
// Auto detect decoding of the response | identity, deflate, & gzip
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_exec($ch);
curl_close($ch);
fclose($fp);
It works, but from hundreds of tests of different images (png, jpg, ico, gif, svg), it is not the most reliable way.
What worked out best is to detect whether an image url has content encoding (e.g. gzip):
// ... image validation ...
// Fetch all headers from URL
$data = get_headers($image_url, true);
// Check if content encoding is set
$content_encoding = isset($data['Content-Encoding']) ? $data['Content-Encoding'] : null;
// Set gzip decode flag
$gzip_decode = ($content_encoding == 'gzip') ? true : false;
if ($gzip_decode)
{
// Get contents and use gzdecode to "unzip" data
file_put_contents($dest_path, gzdecode(file_get_contents($image_url)));
}
else
{
// Use copy method
copy($image_url, $dest_path);
}
For more information regarding gzdecode see this thread. So far this works fine. If there's anything that can be done better, let us know in the comments below.
file_put_contents
etc. – ashleedawg