Приветствую всех, кто проявил внимание к теме!
Столкнулся с простой, на первый взгляд, задачей, в процессе решения которой возникли непредвиденные осложнения. Как, впрочем, и всегда.
Задача: проставить на изображение [основу] (jpg / gif / png) водяной знак (gif / png) с полупрозрачностью.
Особенности:
1) Основа может иметь прозрачный фон.
2) Водяной знак, естественно, имеет прозрачный фон.
3) Водяному знаку нужно добавить полупрозрачность.
4) Результирующее изображение можно делать в формате PNG, если на входе GIF (если это облегчит задачу).
Для двух PNG изображений задача решается функцией imagecopymerge_alpha, написанной Родриго Поло и опубликованной на официальном сайте PHP: http://www.php.net/manual/en/fun...agecopymerge.php (нужно немного промотать вниз).
Но если в паре основа / водяной знак хотя бы одно из изображений в формате GIF, мне не удается добиться нужного эффекта: водяной знак становится полностью черным или видна какая-то его часть (без полупрозрачности).
Есть ли у вас мысли на этот счет?
1. Novascriptum - 27 Октября, 2013 - 15:48:50 - перейти к сообщению
2. deblogger - 01 Ноября, 2013 - 09:41:40 - перейти к сообщению
Потому что GIF не несет с собой альфа-канала. Следовательно этот формат сперва надо особо конвертануть в RGBA.
(Добавление)
Откуда у вас вообще берутся такие gif'ы? Если берутся - ищите функцию которая может их конвертить.
В общих чертах гиф устроен просто. Это массив индексов указывающих на поллитру в которой лежат RGB (8*3, TrueColor) пикселы. Такая хитромудрая система порождена в свое время особенностями харда. Один из таких пикселов в палитре может быть обозначен как "прозрачный". Коню ясно это не пиксел альфаканала, это просто метка, инструкция рендеру: все пикселы которые показывают на этот цвет рендерить пикселами фона. Посклольку никаких коэффициентов не предусмотрено, то рендерится либо пиксел изображения, либо пиксел фона, что приводит к известному при определенных обстоятельствах эффекту бахромы.
Конвертер фактически должен построить альфу по этим самым индексам. Заменив индексы на те самые пикселы из палитры. Можно даже самому написать.
Кстати, в автодесковой реализации гиф мог сдвигать свою палитру во времени. Не сам, но хранилась в нем такая инструкция которая будучи поддержана ПО позволяла анимировать гиф без анимации.
И да, вскрывая гиф вам еще надо об этой самой анимации позаботиься. Короче гемор. Откажитесь от гифа - это проще.
(Добавление)
Откуда у вас вообще берутся такие gif'ы? Если берутся - ищите функцию которая может их конвертить.
В общих чертах гиф устроен просто. Это массив индексов указывающих на поллитру в которой лежат RGB (8*3, TrueColor) пикселы. Такая хитромудрая система порождена в свое время особенностями харда. Один из таких пикселов в палитре может быть обозначен как "прозрачный". Коню ясно это не пиксел альфаканала, это просто метка, инструкция рендеру: все пикселы которые показывают на этот цвет рендерить пикселами фона. Посклольку никаких коэффициентов не предусмотрено, то рендерится либо пиксел изображения, либо пиксел фона, что приводит к известному при определенных обстоятельствах эффекту бахромы.
Конвертер фактически должен построить альфу по этим самым индексам. Заменив индексы на те самые пикселы из палитры. Можно даже самому написать.
Кстати, в автодесковой реализации гиф мог сдвигать свою палитру во времени. Не сам, но хранилась в нем такая инструкция которая будучи поддержана ПО позволяла анимировать гиф без анимации.
И да, вскрывая гиф вам еще надо об этой самой анимации позаботиься. Короче гемор. Откажитесь от гифа - это проще.
3. Novascriptum - 03 Ноября, 2013 - 19:17:49 - перейти к сообщению
Цитата:
Откажитесь от гифа - это проще
Хорошо, бог с ним, с gif'ом, если в нем основа изображения. Но вот водяной знак gif, как я понимаю, можно конвертнуть в rgba без потери качества и нанести на png / jpeg?
4. deblogger - 05 Ноября, 2013 - 04:25:02 - перейти к сообщению
Можно, но как это сделать встроенными функциями я не понял. Готовых решений нет, это значит либо все делается обычно, либо вообще не делается. Надо проверять.
Вы можете открыть файл как байтовый массив и согласно спецификации на gif размочить его.
Вы можете открыть файл как байтовый массив и согласно спецификации на gif размочить его.
5. armancho7777777 - 05 Ноября, 2013 - 11:40:13 - перейти к сообщению
Реализация (Отобразить)
Пример:
PHP:
скопировать код в буфер обмена
скопировать код в буфер обмена
- // Основной холст
- $imagePNG = new Image('sample.png');
- // Водяной знак
- $imageGIF = new Image('sample.gif');
- $x = $imagePNG->width - $imageGIF->width - 20;
- $y = $imagePNG->height - $imageGIF->height - 20;
- $imagePNG->copy($imageGIF->opacity(0.7), $x, $y)->outputType(IMAGETYPE_PNG);
- echo $imagePNG;
P.S. Решение реализовано подобным образом, чтобы его можно было расширить другим функционалом.
Примечание:
Конструктор класса может принимать несколько вариантов аргументов:
либо имя файла,
либо ресурс изображения,
либо 3 аргумента: ширина, высота и массив rgbа(rgb)-цветов для генерации изображения.
В последнем случае третий аргумент не обязателен.
Если не указывать, то сгенерируется прозрачный холст.
Для сохранение изображения в нужном формате просто укажите соответствующее расширение.