How to determine the size of an image without downloading it (in full)?

How to determine the size of an image without downloading it (in full)?

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):

Get image dimensions with Curl
Alternative to CURLOPT_RANGE to grab a specific section

Has anyone been able to put the pieces together (withor without ImageMagick)?

Solutions/Answers:

Answer 1:

How about using ImageMagick’s ping functionality like this:

identify -ping -format "%wx%h" http://www.google.com/logos/giroux1.jpg
482x142

Answer 2:

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.

Answer 3:

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;
}

Answer 4:

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;
}

Our Awesome Free Tools

References

generate php classes in bash

generate php classes in bash

i have this script:
  #!/bin/bash

  if [[ -z "$1" ]] ; then
      echo "Class is required"
      exit 1;
  fi

  if [[ -z "$2" ]] ; then
      package="Default"
  else
      package=$2;
  fi

  echo " $1.class.php

  php -l $1.class.php
  echo "Done";

if i do:
./generate.sh my_class it creates everything with my_class. how can i modify this to: MyClass?
i need to use MyClass for the filename, and the class name etc... later in the code i use the argument (in this case my_class) for some other purposes.
thanks

Solutions/Answers:

Answer 1:

If you want to ensure it’s called MyClass you can add this somewhere after the validations:

fname=$( IFS='_'; for i in ${1,,}; do echo -n ${i^}; done )

And use $fname.class.php

Answer 2:

It looks like it is already set up for that. Just execute ./generate.sh MyClass

Our Awesome Free Tools

References