Загрузка и хранение фотографий в Web приложениях

Почему это важно? На современных web сайтах объем картинок может составлять от 30% до 70% всего размера страницы. Например, объем изображений на Хабре обычно составляет несколько мегабайт.размер фоток на странице

Большинство изображений в Web’e — это фотографии. Профильные фото в соц. сетях, альбом с телефона, профессиональные снимки и т.п. Правильная стратегия и инструменты для работы с фотографиями позволят сделать сайт быстрым для посетителей.

Формат для фотографий Основной формат для хранения фотографий в Web’e — это JPEG. Однако иногда следует использовать и другие форматы.JPEG Хорошо подходит для сложных изображений, т.е. как раз для фотографий. Основной принцип сжатия в этом формате — это уменьшение качества путем уменьшения детализации изображения.JPEG качество

Подбор показателя сжатия может уменьшить размер исходного файла в несколько раз без заметного ухудшения качества. Логика такая: чем ниже качество — тем легче файл. Обычно используют показатель качества от 80 до 90.

Webp Это формат, разработанный специально для обслуживания изображений в Web’e. Может уменьшить размер файла в несколько раз без потери качества. Значительно лучше сжимает фотки, чем JPEG. Однако поддерживается еще не всеми браузерами.PNG и GIF Эти форматы не подходят для фотографий. PNG изображения сохраняются без потери качества и лучше всего подойдут для иконок и графики. Формат GIF имеет ограниченную палитру, однако поддерживает анимацию.Загрузка фотографий на сервер Если на вашем проекте существует необходимость загружать пользовательские фотографии, сначала необходимо выбрать принцип их хранения на сервере.Если вы собираетесь работать с сотнями файлов, стоит выбрать древовидную структуру:

структура хранения фоток

Это позволит избежать ситуации с тысячами файлов в одной папке (это тормозит работу файловой системы и вашу собственную). Лучше всего использовать вложенную структуру из папок длинной в два символа:

$photo = $_FILES['image']['tmp_name']; $name = md5($photo) . '.jpg'; $dir = substr (md5(microtime ()), mt_rand (0, 30), 2) . '/' . substr (md5(microtime ()), mt_rand (0, 30), 2); $path = $dir. '/' . $name; # по этому пути сохраняем фотку Инструменты После загрузки фотографий на сервер, их следует обработать: Уменьшить размер до приемлемого. Нет смысла хранить и показывать оригинал фотографии размером 4000×3000 на сервере. Удалить все метаданные. Иногда объем такой инфы может составлять больше половины веса самого изображения. Провести оптимизацию для уменьшения размера файлов. Это ускорит загрузку у посетителя. image

Для этого существует ряд инструментов.

ImageMagick Сразу после загрузки фотографии на сервер, имеет смысл удалить все метаданные и изменить размер до 1000×1000: # 90 — уровень сжатия в итоговом JPEG файле convert input.jpg -strip -resize 1000×1000 -quality 90 output.jpg GraphicsMagick То же самое с помощью более производительного GraphicsMagick: # изменение размера до 600×500 с уровнем качества в 90 gm convert input.jpg -strip -resize 600×500 -quality 90 output.jpg Jpegtran Этот инструмент уменьшает размер JPEG файлов без потери качества. jpegtran -copy none -optimize -outfile min.image.jpg image.jpg cwebp Утилита позволяет преобразовать изображение в формат Webp. cwebp -q 85 input.jpg -o output.webp Отдача клиенту Фотографии лучше всего отдавать Nginx’ом. Обязательно нужно настроить Cache-control и Keepalive для повышения скорости загрузки страниц: http { …

keepalive_timeout 75s;

server { listen 80; location ~ .\.jpg$ { expires max; } } } Превью (thumbnails) Часто нужно иметь возможность показывать небольшие версии фотографий (например, миниатюра профильной фотки).thumbnail фоткиДля этого необходимо генерировать нужные размеры при загрузке:

convert file.jpg -resize 50×50 file.s.jpg convert file.jpg -resize 250×250 file.m.jpg Тогда у каждого изображения будет соответствующая миниатюра.

Более удобный подход — генерировать превью на лету с помощью, например, Nginx image_filter модуля.

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

Для каждой фотографии нужно сгенерировать webp версию:

cwebp file.jpg -o file.jpg.webp Теперь необходимо отдать соответствующую версию картинки в зависимости от поддержки этого формата браузером:

server { … location ~* ^/.+\.(jpg|jpeg)$ { if ($http_accept ~* «webp») { rewrite (.+) $1.webp; } } … } Облака Облачные технологии развиваются и дешевеют. Если у вас нет специфических задач по обработке фоток, лучше присмотреться к варианту использования внешнего сервиса для их хранения и отдачи.image

Amazon s3 Это облачное хранилище с которым не придется думать о масштабировании. Храните терабайты и не парьтесь. Пример реализации загрузки фотографий на S3 в PHP: $path = 'photo_name.jpg'; $s3 = new S3('ключ', 'секрет'); $s3→putObjectFile ($_FILES['image']['tmp_name'], 'букет', $path, S3:: ACL_PUBLIC_READ, []); После этого можно показывать фотку прямо с Амазона:

… Cloudinary Мощный сервис для работы с фотографиями в облаке. Ресайз, кроп, распознавание лиц, разные форматы, онлайн редактор и другие функции.i.onthe.io Мега простой сервис, распознает возможности браузера и подбирает оптимальный формат отдачи. Поддерживает URL API для ресайза и кропа.Конспект Правильный формат и сжатие фоток могут сэкономить до 70% объема страницы. Используйте только JPEG для фотографий. При возможности включайте поддержку Webp. Imagemagick, Graphicsmagick и Jpegtran для манипуляций и оптимизации фоток. Рассматривайте облачные решения для хранения фоток — это быстро и удобно.

© Habrahabr.ru