Подтвердить что ты не робот

Как определить размер изображения без его загрузки (в полном объеме)?

Я ищу, чтобы получить размеры, ширину и высоту удаленного JPG. Я видел, как это можно сделать, загрузив полное изображение.

Однако было бы идеально, если бы я мог сделать это, загрузив только достаточно, чтобы просто получить эту информацию.

Типичные изображения имеют размер 200 КБ, и для чтения всего лишь несколько К может быть достаточно для JPG:

curl_setopt($ch, CURLOPT_RANGE, "0-4096");

Для справки, я следил за этими ответами/комментариями, но безрезультатно (хотя они могут быть на правильном пути):

Кто-нибудь мог собрать кусочки вместе (без или без ImageMagick)?

4b9b3361

Ответ 1

Мне удалось ответить на мой собственный вопрос, и я включил фрагмент кода PHP.

Единственный недостаток (по крайней мере для меня) заключается в том, что он записывает загрузку частичного изображения в файловую систему до чтения в измерениях с помощью getImageSize.

Для меня 10240 байт - это безопасный предел для проверки изображений jpg размером от 200 до 400 К.

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

Ответ 2

Как насчет использования функций ImageMagick ping следующим образом:

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

Ответ 3

Согласно Получение размера изображения JPEG из его двоичного файла, размер изображения не сохраняется в точном месте в файле. В зависимости от расширения вы можете иметь целую кучу данных в файле до фактического размера, например, в виде большого пальца.

Следующий код С++ должен стать хорошим началом для вашей собственной реализации PHP: http://www.64lines.com/jpeg-width-height. Вы можете легко адаптировать этот код, обратившись к строке, содержащей ваши данные, как массив: myString{$i} вместо data[i]

Вы должны загрузить относительно большой фрагмент данных и проанализировать его, а затем загрузить больше, если это необходимо. Или вы можете загружать блок блоков за кадром, но накладные расходы, вызванные многочисленными подключениями, преследуют цель не загружать весь файл.

Во всяком случае, я не уверен, что преимущества будут оправдывать время, потраченное на это. 200k сейчас ничего.

Ответ 4

Улучшенная версия донохого ответа выше. Он извлекает меньшие байтовые диапазоны для png и gif файлов, как описано здесь.

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