Супер быстрый getimagesize в php


Я пытаюсь получить размер изображения (размеры изображения, ширину и высоту) сотен удаленных изображений и getimagesize это слишком медленно.

Я немного почитал и выяснил, что самым быстрым способом было бы использовать file_get_contents для считывания определенного количества байтов с изображений и изучения размера двоичных данных.

Кто-нибудь пытался сделать это раньше? Как бы я изучил различные форматы? Кто-нибудь видел какую-нибудь библиотеку для этого?

Author: Alfred Bez, 2011-01-08

3 answers

function ranger($url){
    $headers = array(
    "Range: bytes=0-32768"
    );

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($curl);
    curl_close($curl);
    return $data;
}

$start = microtime(true);

$url = "http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg";

$raw = ranger($url);
$im = imagecreatefromstring($raw);

$width = imagesx($im);
$height = imagesy($im);

$stop = round(microtime(true) - $start, 5);

echo $width." x ".$height." ({$stop}s)";

Тест...

640 x 480 (0,20859 с)

Загрузка 32 кб данных сработала для меня.

 86
Author: Dejan Marjanovic, 2012-04-23 20:50:58

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

Он доступен на GitHub здесь: https://github.com/tommoor/fastimage

Пример использования:

$image = new FastImage($uri);
list($width, $height) = $image->getSize();
echo "dimensions: " . $width . "x" . $height;
 24
Author: Tom, 2012-09-26 12:10:00

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

В целом, когда это работало, самой быстрой, как правило, была функция getjpegsize, которую Джеймс Релиеа опубликовал на странице PHP для getimagesize, опередив функцию ranger, предоставленную Деяном выше. http://php.net/manual/en/function.getimagesize.php#88793

Image #1 (787KB JPG on external older server)
getimagesize: 0.47042 to 0.47627 - 1700x2340 [SLOWEST]
getjpegsize: 0.11988 to 0.14854 - 1700x2340 [FASTEST]
ranger: 0.1917 to 0.22869 - 1700x2340

Image #2 (3MB PNG)
getimagesize: 0.01436 to 0.01451 - 1508x1780 [FASTEST]
getjpegsize: - failed
ranger: - failed

Image #3 (2.7MB JPG)
getimagesize: 0.00855 to 0.04806 - 3264x2448 [FASTEST]
getjpegsize: - failed
ranger: 0.06222 to 0.06297 - 3264x2448 * [SLOWEST]

Image #4 (1MB JPG)
getimagesize: 0.00245 to 0.00261 - 2031x1434
getjpegsize: 0.00135 to 0.00142 - 2031x1434 [FASTEST]
ranger: 0.0168 to 0.01702 - 2031x1434 [SLOWEST]

Image #5 (316KB JPG)
getimagesize: 0.00152 to 0.00162 - 1280x720
getjpegsize: 0.00092 to 0.00106 - 1280x720 [FASTEST]
ranger: 0.00651 to 0.00674 - 1280x720 [SLOWEST]
  • ranger не удалось захватить 32768 байт на изображении №3, поэтому я увеличиваю его до 65536 и это сработало, чтобы успешно захватить размер.

Однако есть проблемы, поскольку и ranger, и getjpegsize ограничены в способах, которые делают его недостаточно стабильным для использования. Оба не удалось при работе с большим изображением JPG размером около 3 МБ, но ranger будет работать после изменения количества байтов, которые он захватывает. Кроме того, эти альтернативные варианты имеют дело только с изображениями JPG, что означает, что необходимо использовать условное условие, чтобы использовать их только в JPG и getimagesize в других форматах изображений.

Кроме того, обратите внимание, что первое изображение было на более старом сервере, на котором работала старая версия PHP 5.3.2, где, как и 4 других изображения, были получены с современного сервера (облачная cPanel с MultiPHP, набранная для совместимости с 5.4.45).

Стоит отметить, что облачный сервер справился намного лучше с getimagesize, который превзошел ranger, фактически для всех 4 тестов на облачном сервере ranger был самым медленным. Эти 4 также извлекали изображения с того же сервера, на котором выполнялся код, хотя и отличались счета.

Это заставляет меня задуматься, улучшилось ли ядро PHP в версии 5.4 или повлияла ли версия Apache. Кроме того, это может быть связано с доступностью сервера и нагрузкой на сервер. Давайте не будем забывать, что сети с каждым годом становятся все быстрее и быстрее, так что, возможно, проблема скорости становится все менее актуальной.

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

Как и в случае любого кэширования, оно хорошо работает только в том случае, если содержимое не меняется и есть способ проверить, произошло ли изменение. Таким образом, возможным решением является проверка только заголовков URL-адреса изображения при проверке кэша, и если это не так, сбросьте кэшированную версию и возьмите ее снова с помощью getimagesize.

 3
Author: Exit, 2017-03-09 23:12:22