Wednesday, June 3, 2009

图片分层透明化

给JeRegle的幼儿园分色,给我的是一个gif文件,除了底色白色之外,只有三种颜色。
需要将这三种颜色的点分别提取出来,并背景透明化存成独立文件。

之前处理图片的时候,也给他做过一次背景透明化的东西,用gd库的imagecolortransparent清理背景色。
<?php
$image = imagecreatefromgif('totrans.gif');
$dim = array(imagesx($image), imagesy($image));

var_dump($dim);
$im = imagecreatetruecolor($dim[0], $dim[1]);
$bg = imagecolorallocate($im, 255,255,255);

imagecopyresampled($im, $image, 0, 0, 0, 0, $dim[0], $dim[1], $dim[0], $dim[1]); 

$white = imagecolorallocate($im, 255,255,255);
imagecolortransparent($im, $white);
imagegif($im, 'trans.gif');?>


但是这次分色的时候,发现imagegif出来gif颜色有问题。生成了好几次,觉得有可能是gif色库的问题。印象中标准gif只能描述256种颜色,所以需要一个类似于bmp的调色板的东西。

用imagepng生成之后,继续去颜色,然后列出一个表格:
original:   gif   :   png  
#93B1FD : #94B2FC : #93B1FD
#B6CBFE : #B4CAFC : #B6CBFE
#D9E4FE : #DCE6FC : #D9E4FE

虽然png的颜色没问题,但是给他之后,居然ps没法识别背景的透明化。

突然想到了 ImageMagick。
有打算用imagick或者magickwand for php来试试
但是有点不大靠谱,没时间翻文档。
突然想到ImageMagick的一个二进制程序 convert
印象中见有人用它做过透明化的处理。
先把gd代码的透明化给注视掉,让背景色全为白色,然后上网查了下,
E:\sskaje>convert 4_1.png -background transparent -transparent white 5_1.png
然后把图给他,测试没问题。

php代码:
<?php
/*
original:   gif   :   png  
#93B1FD : #94B2FC : #93B1FD
#B6CBFE : #B4CAFC : #B6CBFE
#D9E4FE : #DCE6FC : #D9E4FE

transparent the background with imagemagick/convert:
 E:\sskaje>convert 4_1.png -background transparent -transparent white 5_1.png
*/
$image = imagecreatefromgif('3.gif');
$dim = array(imagesx($image), imagesy($image));
$prefix = '4_';
$im = imagecreatetruecolor($dim[0], $dim[1]);
$bg = imagecolorallocate($im, 255,255,255);
$white = imagecolorallocate($im, 255,255,255);
$red = imagecolorallocate($im, 255, 0, 0);

$layers = array(
 1 => array(
  imagecolorallocate($im, 0x93,0xb1,0xfd),
  0x93B1FD,
 ),
 2 => array(
  imagecolorallocate($im, 0xb6,0xcb,0xfe),
  0xB6CBFE,
 ),
 3 => array(
  imagecolorallocate($im, 0xd9,0xe4,0xfe),
  0xD9E4FE,
 ),
);

foreach ($layers as $k=>$v)
{
 echo $k, "\n";

 imagecopyresampled($im, $image, 0, 0, 0, 0, $dim[0], $dim[1], $dim[0], $dim[1]); 

 for ($i=0; $i<$dim[0]; $i++)
 {
  for ($j=0; $j<$dim[1]; $j++)
  {
   if (imagecolorat($im, $i, $j) != $v[1])
   {
    imagefill($im, $i, $j, $white);
   }
   else
   {
    imagefill($im, $i, $j, $v[0]);
   }
  }
 }

 #imagecolortransparent($im, $white);
 #imagegif($im, $prefix.$k.'.gif');
 imagepng($im, $prefix.$k.'.png');
}?>

No comments:

Post a Comment