自言自语

I'm Wang Xianyuan, writing for myself, more studying, more experience…

C#生成背景透明的GIF文件

By

在C#中调用Graphics.Clear(Color.Transparent) 生成 gif 格式透明文件时,设置的透明不起作用。使用 Bitmap.MakeTransparent 方法同样不起作用。这两个问题也是微软的设计使然,和 gif 文件格式有关系。下面一段代码可以生成背景透明的GIF文件。

public Bitmap MakeTransparentGif(Bitmap bitmap, Color color)
{
    byte R = color.R;
    byte G = color.G;
    byte B = color.B;

    MemoryStream fin = new MemoryStream();
    bitmap.Save(fin, System.Drawing.Imaging.ImageFormat.Gif);

    MemoryStream fout = new MemoryStream((int)fin.Length);
    int count = 0;
    byte[] buf = new byte[256];
    byte transparentIdx = 0;
    fin.Seek(0, SeekOrigin.Begin);
    //header
    count = fin.Read(buf, 0, 13);
    if ((buf[0] != 71) || (buf[1] != 73) || (buf[2] != 70)) return null; //GIF

    fout.Write(buf, 0, 13);

    int i = 0;
    if ((buf[10] & 0x80) > 0)
    {
        i = 1 << ((buf[10] & 7) + 1) == 256 ? 256 : 0;
    }

    for (; i != 0; i--)
    {
        fin.Read(buf, 0, 3);
        if ((buf[0] == R) && (buf[1] == G) && (buf[2] == B))
        {
            transparentIdx = (byte)(256 - i);
        }
        fout.Write(buf, 0, 3);
    }

    bool gcePresent = false;
    while (true)
    {
        fin.Read(buf, 0, 1);
        fout.Write(buf, 0, 1);
        if (buf[0] != 0x21) break;
        fin.Read(buf, 0, 1);
        fout.Write(buf, 0, 1);
        gcePresent = (buf[0] == 0xf9);
        while (true)
        {
            fin.Read(buf, 0, 1);
            fout.Write(buf, 0, 1);
            if (buf[0] == 0) break;
            count = buf[0];
            if (fin.Read(buf, 0, count) != count) return null;
            if (gcePresent)
            {
                if (count == 4)
                {
                    buf[0] |= 0x01;
                    buf[3] = transparentIdx;
                }
            }
            fout.Write(buf, 0, count);
        }
    }
    while (count > 0)
    {
        count = fin.Read(buf, 0, 1);
        fout.Write(buf, 0, 1);
    }
    fin.Close();
    fout.Flush();

    return new Bitmap(fout);
}

Comments are closed.