Изменение размера изображения средствами PHP

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

Безопасная загрузка изображений и хранение на сервере

Приступая к разработке кода по изменению размеров изображений, стоит решить: каким образом будут хранится картинки? Сам файл изображения следует хранить только на диске, так как записывать его в БД - лишняя трата ресурсов и дискового пространства сервера. А вот значения его высоты, ширины и название имени файла стоит всеже хранить в БД. Если не указывать при выводе картинки её точные размеры, вся разметка страницы может "плыть", по мере загрузки клиенту, так как браузер может узнать размер только после полной загрузки изображения или по параметрам width и height тега <img>. Также в БД, при необходимости, можно сохранить данные описания картинки <img alt="Описание"> и порядковый номер изображения, если планируется отображать несколько штук на одной странице, в заранее определенном порядке.

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

<FilesMatch ".(?i:gif|jpg|jpeg|png)$">
Order Allow, Deny
Allow from all
</FilesMatch>

Код этого файла (работает только для Web-сервера Apache) закрывает доступ на выполнение для всех файлов, кроме файлов с расширениями, указанными в FilesMatch. Т.е. прямой доступ к картинке 1.jpg возможен, а вот при попытке запуска файла shell.php будет выдана ошибка, что доступ к файлу запрещен.

Имена файлов загружаемых изображений необходимо в обязательном порядке проверять, и записывать файл с расширением, соответсвующим типу файла, чтобы не пропустить тот же shell.php. Тип файла определяется не на основании его расширения, а путем просмотра его MIME-типа. Для этого, файл необходимо сначала загрузить, потом перенести в свою временную папку при помощи move_uploaded_file(). Временная папка должа быть в обязательном порядке закрыта от просмотра .htaccess`ом или же имя временного файла необходимо сгенерировать автоматичесски (rg7GhdOidfgsx.file). Также, следует удостоверится - является ли файл изображением? Эта проверка осуществляется с помощью функции getimagesize() - если получены данные о ширине и высоте картинки, значить загружаемый файл точно является изображением.

Меры безопасности не следует доводить до абсурда. Например, если загрузка изображений доступна только доверенным пользователям, не стоит обязательно "ресайзить" изображения, размер которых менее, чем необходимы. Ведь если администратор может использовать HTML-дискрипторы и JS при наполнении сайта содержимым - ничто не помешает ему вставить любой JS в контент напрямую, и не искать, как его встроить в тот же img.gif. Ктомуже, при изменении размеров изображения средствами PHP некоторые картинки могут заметно терять в качестве: потеря прозрачности и др.

Способы смены размеров картинок.

Вернемся к теме статьи, а вопросы кассательно проверки загруженного изображения и записи данных в БД, возможно, будут раскрыты в этой статье познее. Существует 2 основных способа генерации превьюх изображений: пропорциональный и точно соответствующий необходимым размерам с максимально возможным соблюдением пропорциональности.

Примеры способов изменений размеров изображения:
Оригинал 180 на 250
Вариант 1.
Пропорциональное сжатие, чтобы картинка не превышала размер 100 на 100.
Вариант 2A.
Соответствие максимально допустимым размерам 100 на 100, верхняя часть
Вариант 2Б.
Соответствие максимально допустимым размерам 100 на 100, середина

Пропорциональная смена размеров изображения "Вариант 1" позволяет избежать вырезки части изображения. Этот способ уменьшения размеров картинки лучше всего использовать, если изображения размещаются в разнобой по тексту или важно сохранить всё изображение целиком. "Вариант 2" больше подходит для фотоальбомов, где сразу выводится некоторе кол-во фотографий, и если они будут разных пропорций, выглядеть такая фотогалерея, в целом, будет не очень хорошо.

Установлена ли библиотека GD - просмотр с помощью PHP функции phpinfo()
Поддержка GD: enabled/disabled

В скриптах, опубликованных ниже, будет использоваться GD - библиотека для работы с изображениями. GD установлена практически на всх хостингах с поддержкой PHP - и это ее основное преимущество перед ImageMagic. Документацию по библиотеке GD можно посмотреть тут: php.net/gd (eng). Определить, работает ли GD на хостинге, можно с помощью функции библиотеки GD getimagesize(), "натравив" ее на изображение или просмотрев результат работы phpinfo().

Для начала необходимо создать пустое полноцветное изображение предпросмотра с заданными шириной и высотой при помощи функции imagecreatetruecolor($width, $height).

  • $width - ширина уменьшенного изображения;
  • $height - высота уменьшенного изображения.

Функцию imagecreatetruecolor() в официальной документации PHP библиотеки GD рекомендуется использовать вместо более древней imagecreate(), но есть ньюансы, которые необходимо знать, чтобы использовать нужные функции, в зависимости от входных данных. Определится с выбором функции поможет статья: "Imagecreate против imagecreatetruecolor".

Далее, функцией imagecopyresampled() изменяется размер входящей картинки до размеров $width и $height, предварительно созданного пустого изображения. Использовать практически сходную функцию GD imagecopyresized() не рекомендуется. Подробности в статье: "Imagecopyresampled против imagecopyresized GD".

Статья в стадии написания, продолжение следует...

Опубликовано: 2011/05/30
HTML-код ссылки на эту страницу:
<a href="http://petrenco.com/php.php?txt=22" target="_blank">Изменение размера изображения средствами PHP и библиотеки GD. Качественный preview картинок.</a>
14331
Комментарии
Также следует знать, что в самом коде изображения можно спрятать вирус или другую вредоносную программу (php, cgi, js).

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

так вот, imagecopyresampled Делает отличные превьюшки, со сглаживанием, которые даже при сильном увеличении, выглядят гладко и красиво, без разводов и артефактов.

imagecopyresized - же делает превьюшки просто ужасно! туча артефактов высыпает на фото, разводы, при увеличении всё этио лишь заметнее. И притом, что вес картинки больше, чем у предыдущей функции.

Вобщем, по крайней мере для превьюшек, гораздо лучше imagecopyresampled!
Добавить комментарий
Ваш e-mail: (не виден посетителям сайта)
Ваше имя:
Комментарий:
Символы с картинки:
Только выделенные поля формы добавления комментариев обязательны к заполнению.