Но машины все еще не люди, и далеко не всегда будет вырезана нужная область. Старые способы типа вырезать миниатюру 100х100 из левого верхнего угла или из центра отходят на второй план, и на арену выходит смарт-кроп.
Традиционный смарт-кроп
Большинство библиотек для избежания искажения и растягивания фоток используют смарт-кроп. Суть в том, что сначала код ресайзит картинку так, чтобы один из параметров — длина или ширина — соответствовали заданному. Затем проверяет, соответствует ли второй параметр заданному. Если нет, выполняется кроп лишних областей начиная от центра.
Создание миниатюры, допустим, 400х400 будет происходить так:
Загвоздка в том, что далеко не всегда (а точнее почти никогда) самое главное оказывается в самом центре. Чаще всего — какая-то часть главного, но объекты чаще всего так или иначе смещены.
Смарт-кроп на основе энтропии
Общая идея — найти фрагмент картинки, несущий наибольшее количество информации и сохранить его в кропнутой версии.
Как это работает
Сначала картинка ресайзится.
Затем запускается фильтр для определения границ. Картинка становится черно-белой и на ней остаются только контуры обьектов.
Максимально снижается насыщенность и картинка несколько “замыливается”.
Определяется фрагмент с наивысшей энтропией — то есть с наибольшим количеством контуров. Возвращаются координаты этого фрагмента, то есть той части картинки, которую обрезать нельзя ни в коем случае.
Самый сложный этап — поиск фрагмента с наивысшей энтропией. Поиск выполняется фрагментарно — картинка “разрезается” на 25 полосок, подсчитывается энтропия для каждой из них и сравнивается. Затем определяется группа с максимальной энтропией.
Применение
Для применения удобно использовать вот эту библиотеку.
Требования: PHP 5.3 с расширением Imagick. Применяется в три этапа.
Инициализация:
$center = new CropEntropy($imagePath);
Ресайз и кроп:
$croppedImage = $center->resizeAndCrop($width, $height);
Cохранение нового изображения:
$croppedImage->writeimage($newImagePath);
Попробовать кроп на основе энтропии можно тут, задав требуемый размер миниатюры.
Иногда алгоритм безошибочно определяет самую важную область. Но иногда и ошибается, особенно при нестандартных — неквадратных параметрах кропа (300х100). Но вот очень хороший результат с теми же параметрами, но другой фоткой. Идеального результата алгоритм не гарантирует, но тем не менее является одним из лучших способов автокропа.
Конспект
- Один из лучших способов автоматизации кропа — кроп на основе энтропии.
- Алгоритм определяет фрагмент с наибольшим количеством информации и сохраняет его в кропнутой версии.
- Преимущества и недостатки способа можно проверить этим инструментом.
Комментарии (17)
Chris_Griffin
12.06.2015 12:34+3Полагаю, что если не реализация, то идея алгоритма взята здесь codegeekz.com/cropping-images-entrop.
Были идеи сделать перевод на хабре, но так руки и не дошли.
johniek_comp
12.06.2015 12:38+2Почему у Вас на сайте нет валидации, sendmail?mail= можно что угодно написать, все равно выдаст «ok»? Зачем писать ок в любом случае, если «error» скорее всего не предусмотрен?
lostpassword
12.06.2015 13:02-12Можете назвать меня ханжой, но жопа в ленте хабра мне совершенно не нравится.
Даже если это рисованная жопа Барта Симпсона.Klaster
12.06.2015 15:35+27У меня серьезнее проблема, я почему то вместо умный кроп, Читаю укроп и сразу вижу жопу. Долбанная политика.
david_mz
12.06.2015 13:04+7Это ваш сервис, да?
Я бы посоветовал помимо плотности деталей использовать нахождение лиц на фото (opencv это вполне неплохо умеет). Лицо для человеческого восприятия гораздо важнее любых других деталей. Если на фото есть лица, то их расположению должен отдаваться приоритет. Как-то так делает Твиттер при обрезке фотографий в твитах.Agent_Smith
12.06.2015 14:54В одном iOS приложении использовал FaceImageView для аватарок. Она использует CoreImage для определиня лиц, и автоматически выравнивает по этим областям картинку.
saggid
12.06.2015 13:13+3По-моему, всё-таки лучше человеку дать возможность самому указать нужную область, как это нынче делается на всех популярных онлайн-сервисах. Для этого есть хорошая JS-библиотека под названием Jcrop. Показываем с помощью неё клиенту изображение, он выделяет нужную область, и потом её мы и вырезаем и делаем аватаркой. Я на нескольких сайтах использовал такой подход, получается очень удобно и качественно.
relgames
12.06.2015 13:57+15Действительно — самое важное осталось :) i.onthe.io/crop?r=6cd1d969906ea893c49fd4feebdf3053
alexeygrigorev
12.06.2015 20:26Картинка уже умерла? Ничего не отображает
alexeygrigorev
12.06.2015 20:31Отбой, т.к. картинка раздается через 88-й порт, мой фаейрвол ее обрезал. Через VPN все ок
dom1n1k
12.06.2015 14:35+2Позднее стоит написать, что все эти статьи дали вашем сервисам в смысле популярности :) Краткосрочной и долгосрочной. Это отдельная и очень интересная тема.
lleo_aha
Рискну конечно погореть, но где тут PHP то? Тут больше похоже на рекламу онлайн-сервиса вроде бы :)