Pull to refresh
0
Rating

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

.io corporate blog PHP *Image processing *

Почему это важно?


На современных 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 1000x1000 -quality 90 output.jpg


GraphicsMagick

То же самое с помощью более производительного GraphicsMagick:

# изменение размера до 600х500 с уровнем качества в 90
gm convert input.jpg -strip -resize 600x500  -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 50x50 file.s.jpg
convert file.jpg -resize 250x250 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, []);


После этого можно показывать фотку прямо с Амазона:
...
<img src="https://s3-eu-west-1.amazonaws.com/букет/photo_name.jpg"/>
...


Cloudinary

Мощный сервис для работы с фотографиями в облаке. Ресайз, кроп, распознавание лиц, разные форматы, онлайн редактор и другие функции.

i.onthe.io

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

Конспект


  • Правильный формат и сжатие фоток могут сэкономить до 70% объема страницы.
  • Используйте только JPEG для фотографий.
  • При возможности включайте поддержку Webp.
  • Imagemagick, Graphicsmagick и Jpegtran для манипуляций и оптимизации фоток.
  • Рассматривайте облачные решения для хранения фоток — это быстро и удобно.
Tags:
Hubs:
Total votes 35: ↑31 and ↓4 +27
Views 94K
Comments Comments 81

Information

Website
onthe.io
Employees
11–30 employees
Registered