PHP-тест для поврежденных (но, по-видимому, хороших) изображений

У меня есть простой скрипт загрузки изображения, который использует SimpleImage.php (http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/) для изменения размера и сохранения 2 копий загруженное изображение.

Массовой проверки не требуется, просто проверяется, что он существует и что расширение файла в порядке, а также вызов exif_imagetype();.

До сих пор это работало без проблем, пока я не попытался загрузить, казалось бы, нормальный jpeg, который оказался невидимым (и непроверяемым?) поврежденным. Что-то в этом было не так, но я очень мало знаю о повреждении изображения - оно выглядело нормально и открывалось без проблем на чем-либо, но когда я попытался сохранить масштабированную копию в своем скрипте, я получил белую страницу.

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

Я изменил размер копии с помощью Photoshop (прогнозированный размер файла дал мне несколько странные цифры — 45 мегабайт для jpeg высшего качества), и она была загружена без проблем.

Итак, мой вопрос: как мне проверить это?

Изображение, о котором идет речь, находится здесь: http://chinawin.co.uk/broken.jpg / /осторожно, 700к

примечания: я тестировал с похожими разрешениями, размерами изображений и именами, все остальное работало, кроме этого изображения.

ОБНОВЛЕНИЕ: Путем проб и ошибок я сузил место, где скрипт прерывается, до строки, где я загружаю изображение в var для SimpleImage. Как ни странно, это вторая строка, которая делает это (первая — для создания большой копии, эта — для создания эскиза). Комментирование означает, что все остальное работает нормально... возможно, некоторый рефакторинг позволит избежать этой проблемы.

2-е обновление: вот фрагмент кода и некоторый контекст из строки, которая не работает:

//check if our image is OK
if ($image && $imageThumb) 
{
    //check if image is a jpeg
    if (exif_imagetype($_FILES[$k]['tmp_name']) == IMAGETYPE_JPEG)
    {
        list($width, $height, $type, $attr) = getimagesize($_FILES[$k]['tmp_name']);
        //echo 1;
        $image = new SimpleImage(); 
        //echo 2;               
        $image->load($_FILES[$k]['tmp_name']);      
        //echo 3;
        $imageThumb = new SimpleImage();
        //echo 4;

        //this next line topples my script, but only for that one image - why?:
        $imageThumb->load($_FILES[$k]['tmp_name']);
        //echo '5<br/><br/>-------<br/>';
        //do stuff, save & update db, etc
    }
}

Окончательное редактирование: оказалось, что моему скрипту не хватило памяти, и на то есть веская причина — изображение 4900x3900 с 240 ppi оказывается около 48 мегабайт при загрузке в память дважды — так что я использовал, вероятно, > 90 мегабайт оперативной памяти, за изображение.

Снимаю шляпу перед @Pekka за то, что заметил это.

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


person totallyNotLizards    schedule 03.10.2011    source источник


Ответы (1)


Скорее всего, это проблема с памятью: ваш JPG очень большой (более 4000 x 4000 пикселей) и в несжатом виде действительно займет около 48 мегабайт оперативной памяти.

Активируйте отчеты об ошибках, чтобы убедиться. Если это причина, см., например. здесь о том, что делать: Загрузка изображений с помощью PHP и нажатие лимит памяти скрипта

person Pekka    schedule 03.10.2011
comment
Фатальная ошибка: Исчерпан допустимый размер памяти 134217728 байт (попытка выделить 19600 байт) в /my_path/SimpleImage.php в строке 28 - person totallyNotLizards; 03.10.2011
comment
Спасибо, нашел причину :) - person totallyNotLizards; 03.10.2011