GIF的透明处理
这是昨天别人让我帮忙写的一个程序,参考了网上的一些文章。实现很简单的功能,就是把一个背景不透明的gif转化成为透明的gif图,功能也很不完善,只是有个原理罢了。我也不多废话,请看程序代码。
源代码如下:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace ifyr.util {
class TransImage {
static void ConvertTo256ColorGIF(string src, string dst) {
//取源图
Bitmap source = new Bitmap(src);
int Width = source.Width, Height = source.Height;
//取调色板
Bitmap tbitmap = new Bitmap( 1, 1, PixelFormat.Format8bppIndexed );
ColorPalette pal = tbitmap.Palette;
tbitmap.Dispose();
//获得原来的索引表
//这里还有改进余地,可以去掉不需要的索引,以减小图片大小
int index = 0;
foreach(Color color in source.Palette.Entries) {
if(color.R == 0&& color.G == 0 && color.B == 0) {
//0表示完全透明,使用黑色作为背景色
pal.Entries[index++] = Color.FromArgb(0,0,0,0);
} else {
//缺省认为其他颜色不是透明色
pal.Entries[index++] = color;
}
}
//画新图
Bitmap target = new Bitmap(Width,Height,PixelFormat.Format8bppIndexed);
target.Palette = pal;
//取图中存放数据的位置,锁定之
BitmapData bitmapData = target.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
IntPtr pixels = bitmapData.Scan0;
//内存操作,所以只能用unsafe代码
unsafe {
byte * pBits = (byte *)pixels.ToPointer();
uint stride = (uint)Math.Abs(bitmapData.Stride);
for ( uint row = 0; row < Height; ++row ) {
for ( uint col = 0; col < Width; ++col ) {
byte * p8bppPixel = pBits + row*stride + col;
Color pixel = source.GetPixel((int)col, (int)row);
index = 0;
while(index < 256) {
if(pixel.R == pal.Entries[index].R &&
pixel.G == pal.Entries[index].G &&
pixel.B == pal.Entries[index].B) {
break;
}
index ++;
}
if(index == 256) {
index = 0;
}
*p8bppPixel = (byte)index;
}
}
}
//释放内存,保存文件,释放资源
target.UnlockBits(bitmapData);
target.Save(dst,ImageFormat.Gif);
target.Dispose();
source.Dispose();
}
//256灰度透明图片,原理方法和上面的一样
static void ConvertTo256GrayGIF(string src, string dst) {
Bitmap source = new Bitmap(src);
int Width = source.Width, Height = source.Height;
Bitmap target = new Bitmap(Width,Height,PixelFormat.Format8bppIndexed);
Bitmap tbitmap = new Bitmap( 1, 1, PixelFormat.Format8bppIndexed );
ColorPalette pal = tbitmap.Palette;
tbitmap.Dispose();
for(int i = 0; i < 256; i ++) {
pal.Entries[i] = Color.FromArgb(255,i,i,i);
}
pal.Entries[0] = Color.FromArgb(0,0,0,0);
target.Palette = pal;
Rectangle rect = new Rectangle(0, 0, Width, Height);
BitmapData bitmapData = target.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
IntPtr pixels = bitmapData.Scan0;
unsafe {
byte * pBits = (byte *)pixels.ToPointer();
uint stride = (uint)Math.Abs(bitmapData.Stride);
for ( uint row = 0; row < Height; ++row ) {
for ( uint col = 0; col < Width; ++col ) {
byte * p8bppPixel = pBits + row*stride + col;
Color pixel = source.GetPixel((int)col, (int)row);
*p8bppPixel = (byte)((pixel.R *0.299) + (pixel.G *0.587) + (pixel.B *0.114) + 0.5);
}
}
}
target.UnlockBits(bitmapData);
target.Save(dst,ImageFormat.Gif);
target.Dispose();
source.Dispose();
}
}
}
发现关键字突显的技术真是很有用啊,现在看清一色的代码就头晕……