В настоящее время я использую ImageMagick для определения размера изображений, загружаемых на сайт. Вызывая ImageMagick «identify» в командной строке, требуется около 0,42 секунды, чтобы определить размеры JPEG размером 1 МБ вместе с тем фактом, что это JPEG. Я считаю это немного медленным.
Использование библиотеки Imagick PHP происходит еще медленнее, поскольку она пытается загрузить в память весь 1 МБ перед обработкой изображения (в данном случае просто определяя его размер и тип).
Есть ли какие-либо решения для ускорения этого процесса определения типа файла и размеров произвольного файла изображения? Я могу жить с этим, поддерживая только JPEG и PNG. Для меня важно, чтобы тип файла определялся по заголовкам файла, а не просто по расширению.
Обновлено: решением может быть инструмент командной строки UNIX, вызываемый PHP, очень похоже на то, как я использую ImageMagick на данный момент.






Если вы используете PHP с поддержкой GD, вы можете попробовать getimagesize ().
Истинный. Я не знаю другого способа, кроме как написать это самостоятельно и сохранить только часть изображения в памяти за раз, но это будет зависеть от типа изображения.
It's important to me that the file type is determined by looking at the file's headers and not simply the extension.
Для этого вы можете использовать команду unix 'file' (или некоторую функцию php, которая реализует ту же функциональность).
/tmp$ file stackoverflow-logo-250.pngstackoverflow-logo-250.png: PNG image data, 250 x 70, 8-bit colormap, non-interlaced
Я только что быстро протестировал это в командной строке, и это тоже кажется довольно медленным, потребовалась хорошая секунда, чтобы определить тип файла JPG. Кажется, что он кеширует результат, но это не представляет особого интереса, так как я тестирую изображение только один раз.
Отчасти это, вероятно, время, необходимое для анализа волшебного файла. Вы можете запустить файл сразу для нескольких изображений. Или вы можете создать волшебный файл меньшего размера, содержащий только обычные типы файлов изображений.
Ты пытался
identify -ping filename.png
?
Хороший звонок, это примерно в 20 раз быстрее :) Описание этой опции заставляет меня задаться вопросом, почему это не стандартное поведение идентификации? В любом случае проблема решена и большое спасибо.
На самом деле, чтобы использовать getimagesize (), вам нужно, чтобы НЕТ был скомпилирован с GD.
Вы также можете использовать mime_content_type (), чтобы получить тип MIME.
Извините, я не могу добавить это как комментарий к предыдущему ответу, но у меня нет репутации. Проведя быстрое и грязное тестирование, я также обнаружил, что exec ("identify -ping ... примерно в 20 раз быстрее, чем без -ping. Но getimagesize (), похоже, еще примерно в 200 раз быстрее.
Поэтому я бы сказал, что getimagesize () - более быстрый метод. Я тестировал только jpg, а не png.
тест просто
$files = array('2819547919_db7466149b_o_d.jpg', 'GP1-green2.jpg', 'aegeri-lake-switzerland.JPG');
foreach($files as $file){
$size2 = array();
$size3 = array();
$time1 = microtime();
$size = getimagesize($file);
$time1 = microtime() - $time1;
print "$time1 \n";
$time2 = microtime();
exec("identify -ping $file", $size2);
$time2 = microtime() - $time2;
print $time2/$time1 . "\n";
$time2 = microtime();
exec("identify $file", $size3);
$time2 = microtime() - $time2;
print $time2/$time1 . "\n";
print_r($size);
print_r($size2);
print_r($size3);
}
Но предоставляет ли GD способ определения типа файла в соответствии с его содержимым (а не назначенным ему расширением)? Также вы должны измерить время, необходимое для загрузки изображения в GD, поскольку я не занимаюсь никакой другой обработкой, кроме определения размера файла.
Я добавил тест к своему ответу. Я не знаю, загружает ли GD файл изображения полностью в память или нет, поскольку я не смотрю память. Но я улавливаю полное время, необходимое для выполнения команды. Также getimagesize () также возвращает тип пантомимы.
Спасибо за все усилия, я протестировал его вживую, и он действительно в 250 раз быстрее, чем решение -ping. Так что примерно в 5000 раз быстрее, чем исходный метод, который я использовал, неплохо :)
exif_imagetype () быстрее, чем getimagesize ().
$ filename = "somefile";
$ data = exif_imagetype ($ имя файла);
эхо "<PRE>";
print_r ($ данные);
эхо "</PRE>";
выход:
Array (
[FileName] => somefile
[FileDateTime] => 1234895396
[FileSize] => 15427
[FileType] => 2
[MimeType] => image/jpeg
[SectionsFound] =>
[COMPUTED] => Array
(
[html] => width = "229" height = "300"
[Height] => 300
[Width] => 229
[IsColor] => 1
)
)
Если вы используете PHP, я бы посоветовал использовать библиотеку Imagick вместо вызова exec(). Вам нужна функция Imagick :: pingImage ().
GD, вероятно, столкнется с той же проблемой скорости, поскольку он загрузит изображение в память ...