Как смешивать изображения, используя режим смешивания Photoshop "темный цвет"?
Мне нужно отобразить загруженные пользователем логотипы на фоновом изображении. Фон логотипа должен быть прозрачным.
Проблема заключается в том, что большинство пользователей не знают, как сделать свои изображения прозрачными, не говоря уже о том, как использовать альфа-прозрачность, поэтому большинство загружаемых логотипов имеют белый фон.
В Photoshop отображение этих логотипов на фоне отлично работает, когда вы выбираете "Темный цвет" в качестве режима наложения для слоя.
Я пытаюсь добиться того же в PHP, поэтому я могу сделать это без Photoshop.
Есть идеи?
4 ответа
Я могу придумать два возможных решения.
Можно было бы использовать смешение пикселей на уровне клиента с javascript. Это может быть немного тяжелым процессором, так что, вероятно, это не лучшее решение, особенно для мобильных телефонов и других легких устройств. Существует библиотека, называемая pixastic, которая позволяет использовать некоторые режимы наложения в стиле Photoshop.
Другим решением будет обработка загруженного изображения с помощью gd2 в php и воссоздание логотипа с прозрачностью путем замены цвета фона. В этом случае вы должны знать, какой цвет фона они использовали. И что тогда, если они также используют тот же цвет в логотипе? Вы не хотели бы также сделать это прозрачным.
Посмотрите на следующие функции PHP (среди прочего в семье):
imagealphablending
imagecolortransparent
Лично я предпочел бы метод PHP, который обрабатывает изображение и создает постоянный файл для повторного использования там, где это необходимо. Но, что еще лучше, я бы не стал полагаться на то, что обычный пользователь будет создавать логотипы.
Если вам действительно нужно, чтобы пользователи создавали файлы такого типа, вам следует создать веб-инструмент, позволяющий им указывать прозрачные области, например, редактор значков Visual Studio.
Лично у меня были лучшие результаты с магией изображений, чем с GD, но она доступна не на всех платформах http://php.net/manual/en/imagick.painttransparentimage.php
// Loads image
$im = new Imagick($source);
// Apply fuzz
$im->paintTransparentImage($im->getImagePixelColor(0, 0), 0, $fuzz);
// Writes image
$im->setImageFormat('png');
$im->writeImage($target);
$im->destroy();
Обратите внимание, что $im->getImagePixelColor(0, 0)
получает цвет пикселя в левом верхнем углу изображения, если это должно работать с любым цветом BG, настройте $fuzz
в зависимости от того, насколько перья логотип
Также http://www.php.net/manual/en/imagick.trimimage.php очень полезен для удаления пустого пространства в изображениях.
Я не уверен насчет внутренних компонентов PS, но в своей собственной реализации (не на PHP, заметьте) я подошел к задаче следующим образом:
- Извлечение яркости переднего и заднего плана
- Сравните яркость переднего и заднего плана, чтобы создать маску пикселей
- Назначьте вывод на основе производной маски.
Моя попытка универсального псевдокода:
Yfg = FG(:,:,1)*0.299 + FG(:,:,2)*0.587 + FG(:,:,3)*0.114;
Ybg = BG(:,:,1)*0.299 + BG(:,:,2)*0.587 + BG(:,:,3)*0.114;
mask = (Yfg > Ybg);
R = BG(mask) + FG(~mask);
Это, конечно, отличается от режима "Darken", который просто делает реляционное смешение для каждого канала RGB.
Я не уверен, сколько хлопот эта операция будет в PHP. Я больше знаком со смешиванием изображений, чем с PHP.
Эта функция, кажется, соответствует вашим потребностям.
http://www.php.net/manual/en/function.imagecolortransparent.php
В противном случае вам, вероятно, придется пройти через все пиксели, сравнивая их с пикселем ниже и выбирая более темный для вашего результирующего изображения.