Reputation: 14123
I'm looking to get the dimensions, width and height, of a remotely hosted JPG. I have seen how it is possible to do this by downloading the full image.
However, it would be ideal if I could do this by downloading only enough to just get this information.
Typical images are 200K in size and reading in just a few K might at the beginning might be enough for JPGs:
curl_setopt($ch, CURLOPT_RANGE, "0-4096");
For reference, I've followed these answers/comments but to no avail (though they might be on the right track):
Has anyone been able to put the pieces together (withor without ImageMagick)?
Upvotes: 14
Views: 6421
Reputation: 207405
How about using ImageMagick's ping
functionality like this:
identify -ping -format "%wx%h" http://www.google.com/logos/giroux1.jpg
482x142
Upvotes: 7
Reputation: 1374
An improved version of donohoe's answer above. This one retrieves smaller byte ranges for png and gif files as described here.
function remoteImage($url){
$filename = parse_url($url);
$pi = pathinfo($filename['path'],PATHINFO_EXTENSION);
switch ($pi) {
case "jpg" :
$range = "0-15000";
break;
case "jpeg" :
$range = "0-10000";
break;
case "png":
$range = "0-100";
break;
case "gif":
$range = "0-10";
break;
default:
$range = "0-15000";
break;
}
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch, CURLOPT_RANGE, $range);
$fn = "partial2.png";
$raw = curl_exec($ch);
$result = array();
if(file_exists($fn)){
unlink($fn);
}
if ($raw !== false) {
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status == 200 || $status == 206) {
$result["w"] = 0;
$result["h"] = 0;
$fp = fopen($fn, 'x');
fwrite($fp, $raw);
fclose($fp);
$size = getImageSize($fn);
if ($size===false) {
// Cannot get file size information
} else {
// Return width and height
list($result["w"], $result["h"]) = $size;
}
}
}
curl_close ($ch);
return $result;
}
Upvotes: 4
Reputation: 14123
I managed to answer my own question and I've included the PHP code snippet.
The only downside (for me at least) is that this writes the partial image download to the file-system prior to reading in the dimensions with getImageSize
.
For me 10240 bytes is the safe limit to check for jpg images that were 200 to 400K in size.
function remoteImage($url){
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch, CURLOPT_RANGE, "0-10240");
$fn = "partial.jpg";
$raw = curl_exec($ch);
$result = array();
if(file_exists($fn)){
unlink($fn);
}
if ($raw !== false) {
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status == 200 || $status == 206) {
$result["w"] = 0;
$result["h"] = 0;
$fp = fopen($fn, 'x');
fwrite($fp, $raw);
fclose($fp);
$size = getImageSize($fn);
if ($size===false) {
// Cannot get file size information
} else {
// Return width and height
list($result["w"], $result["h"]) = $size;
}
}
}
curl_close ($ch);
return $result;
}
Upvotes: 3
Reputation: 26597
According to Getting Image size of JPEG from its binary, the size of the image isn't stored in a precise location in the file. Depending on the extension, you can have a whole bunch of data in the file before the actual size, a thumbmail for example.
The following C++ code should be a good start for your own PHP implementation : http://www.64lines.com/jpeg-width-height. You can easily adapt this code by accessing the string containing your data like an array : myString{$i}
instead of data[i]
You should load a relatively large chunk of data and parse it, then load more if necessary. Or you can load the file block by block, but the overhead caused by the numerous connections defeat the purpose of not loading the entire file.
Anyhow, I'm not sure the benefits will justify the time you spend on this. 200k is nothing nowadays.
Upvotes: 5