Проблема с прозрачными гифами. Оттенки черного тоже становятся прозрачными...

Kup

Новичок
Проблема с прозрачными гифами. Оттенки черного тоже становятся прозрачными...

Здравствуйте.

У меня есть проблема, которую сам решить я не могу, хотя вожусь уже почти сутки. Возможно я что-либо недопонимаю в теории гифов и тп, не знаю.

Собственно, сама проблема.

Есть исходный гиф, с прозрачной областью.
Есть второй гиф (гиф2).

Нужно создать картинку, наложив гиф2 на гиф, причем гиф2 меньше чем гиф и прозрачная область должна сохраниться.

Сделал черный цвет в качестве прозрачного, и на первый взгляд - все работает. Но для картинок (гиф2) с черными пикселями выходит косяк - эти пиксели становятся прозрачными. С этой проблемой я бы справился, но, похоже, прозрачными становятся не только чисто черные пиксели.
Причем для разных гиф2 - по-разному.

вот что получается, если вообще не решать эту проблему -
http://www.1kiss.ru/img/photos/128/lets/1.gif

если решать её следующим образом, то для части фоток (гиф2) это помогает, а для части - не совсем.

Метод решения:

PHP:
for ($ix=0; $ix<$real_width; $ix++)
	for ($iy=0; $iy<$real_height; $iy++)
    {
	    $rgb = ImageColorAt($face_img, $ix, $iy);

	    $r = ($rgb >> 16) & 0xFF;
	    $g = ($rgb >> 8) & 0xFF;
	    $b = $rgb & 0xFF;

        //print $r." : ".$g." : ".$b." : "."<br>";

	    if (($r+$g+$b)<=50)
        {
		   $face_reblack = imagecolorallocate($face_img, $r+10, $g+10, $b+10);
		   imagesetpixel($face_img, $ix, $iy,$face_reblack);
        }
    }
результат - для одних фоток - практически идеально, для других - вот - http://www.1kiss.ru/img/photos/128/lets/2.gif

причем если менять константы в if (50, 10) то можно подобрать нужные для получения правильного результата, но они не подойдут для другой картинки.

Понимаю, что эта тема, возможно, уже неоднократно обсуждалась на форуме, но я не смог подобрать правильных слов для поиска. Так что если кто просто ткнет меня носом в другую тему, где есть решение этой проблемы - буду только благодарен.

Заранее спасибо всем!
 

440hz

php.ru
это ресайз с прозрачностью. наложение аналогично ...
PHP:
$src_trans = imagecolortransparent($src); 
$dst = imagecreate($NW,$NH); 
imagepalettecopy($dst,$src); 
imagefill($dst,0,0,$src_trans); 
imagecolortransparent($dst,$src_trans); 
imagecopyresampled($dst,$src,0,0,0,0,$NW,$NH,$W,$H);
p.s. картинка ... гм ...
 

Kup

Новичок
Спасибо за ответ. Использовал
$src_trans = imagecolortransparent($src); для выставления прозрачного цвета - стало намного лучше!

НО! Все равно сохранилась проблема. При добавлении немного разных "гиф2" (см. мой первый пост) иногда остается фон - причем может быть разного цвета...

Примеры:

http://www.1kiss.ru/img/photos/128/lets/6.gif - с этой фоткой все прекрасно!
http://www.1kiss.ru/img/photos/128/lets/5.gif - а на этой откуда-то взялся синий фон... :(

Единственная существенная разница по сравнению с кодом, который приводит 440hz - вместо imagecreate использую imagecreatetruecolor... Проблема видимо в этом...

При использовании imagecreate - всё получается нормально -
http://www.1kiss.ru/img/photos/128/lets/7.gif
за исключением качества... :(

Можно ли как-нибудь использовать imagecreatetruecolor и при этом не испытывать проблем со случайно появляющимся фоном?
 

ksnk

прохожий
Kup
Можно. К примеру так:
PHP:
$dst = imagecreatetruecolor($NW,$NH);  
imagefill($dst,0,0,imagecolortransparent($src));  
imagecopyresampled($dst,$src,1,1,0,0,$NW-1,$NH-1,$W,$H);
imagetruecolortopalette($dst,false,256);
imagecolortransparent($dst,imagecolorat($dst,0,0));
Тут сделан финт - копируется так, чтобы осталась "прозрачная рамка" так как функция ресамплирования может поменять цвет довольно свободным образом.
 

ksnk

прохожий
:) $vin - виньетка, $src - фотография 120,120 - левый верхний угол на виньетке, куда вставляем картинку
PHP:
define('XCOL',60);
imagetruecolortopalette($vin,false,XCOL); 
$dst = imagecreatetruecolor($NW,$NH);  
imagecopyresampled($dst,$src,0,0,0,0,imagesx($dst),imagesy($dst),imagesx($src),imagesy($src)); 
imagetruecolortopalette($dst,false,256-XCOL); // 60 - XCOL
imagecopy($vin,$dst,120,120,0,0,imagesx($dst),imagesy($dst));
imagecolortransparent($vin,imagecolorat($vin,0,0));
Ну тогда - вот.
Общий смысл :
- делаем изображение виньетки с минимально допустимым количеством цветов XCOL
- делаем resample основной картинки и преобразуем его в палитровое и количеством цветов 256-XCOL
- клеим картинки imagecopy
- устанавливает прозрачность
 

Kup

Новичок
Akick
дак там идет добавление водяных знаков... как мне это может помочь?

ksnk
а ведь truecolor при этом теряется? просто многие фотки с малым количеством цветов смотрятся очень плохо...
 

ksnk

прохожий
Kup
а ведь truecolor при этом теряется?
При чем тут TrueColor? Нужно же получить картинку с прозрачным цветом, а такое бывает только в Gif'е. А Gif по версии GD - имеет палитру в 256 цветов. А не очень уверен насчет PNG, но imho, это тот-же GIF, только вид сбоку...
Если качество картинки не устраивает - оставляет поменьше цветов на виньетку...
 
Сверху