.NET Framework和Gif透明度

.NET Framework和Gif透明度,.net,gdi+,wic,.net,Gdi+,Wic,在Windows 7(以及新的图像编解码器:WIC)之前,我使用以下(非常快但不干净)方法创建以白色作为透明颜色的Gif编码图像: MemoryStream target = new memoryStream(4096); image.Save(target, imageFormat.Gif); byte[] data = target.ToArray(); // Set transparency // Check Graphic Control Extension signature (0x

在Windows 7(以及新的图像编解码器:WIC)之前,我使用以下(非常快但不干净)方法创建以白色作为透明颜色的Gif编码图像:

MemoryStream target = new memoryStream(4096);
image.Save(target, imageFormat.Gif);
byte[] data = target.ToArray();

// Set transparency
// Check Graphic Control Extension signature (0x21 0xF9)
if (data[0x30D] == 0x21 && data[0x30E] == 0xF9)
   data[0x313] = 0xFF; // Set palette index 255 (=white) as transparent
这种方法之所以有效,是因为.NET使用索引255为白色的标准调色板对Gif进行编码

然而,在Windows7中,这种方法不再有效。似乎标准调色板已更改,现在索引251为白色。不过,我不能肯定。也许新的Gif编码器正在根据使用的颜色动态生成调色板


我的问题:有人了解Windows 7的新Gif编码器吗?有什么好的、快速的方法可以使白色透明?

您确定这是Windows 7的问题,而不是代码的其他问题吗


研究表明,任何指数都可以用来提高透明度。您可能需要检查图像,以确保启用透明度的相应位已设置为on。如果不是,则您选择的调色板索引将被忽略。

我找到了一种更好的方法,可以将白色设置为gif编码图像的透明色。 它似乎适用于由GDI+和WIC(Windows 7)编码器编码的Gif。 下面的代码在Gif的全局图像表中搜索白色的索引,并使用此索引在图形控件扩展块中设置透明颜色

 byte[] data;

// Save image to byte array
using (MemoryStream target = new MemoryStream(4096))
{
    image.Save(target, imageFormat.Gif);
    data = target.ToArray();
}

// Find the index of the color white in the Global Color Table and set this index as the transparent color
byte packedFields = data[0x0A]; // <packed fields> of the logical screen descriptor
if ((packedFields & 80) != 0 && (packedFields & 0x07) == 0x07) // Global color table is present and has 3 bytes per color
{
    int whiteIndex = -1;
    // Start at last entry of Global Color Table (bigger chance to find white?)
    for (int index = 0x0D + (3 * 255); index > 0x0D; index -= 3)
    {
        if (data[index] == 0xFF && data[index + 1] == 0xFF && data[index + 2] == 0xFF)
        {
            whiteIndex = (int) ((index - 0xD) / 3);
            break;
        }
    }

    if (whiteIndex != -1)
    {
        // Set transparency
        // Check Graphic Control Extension signature (0x21 0xF9)
        if (data[0x30D] == 0x21 && data[0x30E] == 0xF9)
            data[0x313] = (byte)whiteIndex;
    }
}

// Now the byte array contains a Gif image with white as the transparent color
byte[]数据;
//将图像保存到字节数组
使用(MemoryStream目标=新的MemoryStream(4096))
{
image.Save(目标,imageFormat.Gif);
data=target.ToArray();
}
//在全局颜色表中查找白色的索引,并将此索引设置为透明颜色
字节packedFields=数据[0x0A];//逻辑屏幕描述符的名称
如果((packedFields&80)!=0&&(packedFields&0x07)==0x07)//全局颜色表存在,并且每个颜色有3个字节
{
int-whiteIndex=-1;
//从全局颜色表的最后一个条目开始(找到白色的可能性更大?)
对于(int index=0x0D+(3*255);index>0x0D;index-=3)
{
如果(数据[索引]==0xFF和数据[索引+1]==0xFF和数据[索引+2]==0xFF)
{
白索引=(int)((索引-0xD)/3);
打破
}
}
如果(白索引!=-1)
{
//设置透明度
//检查图形控件扩展签名(0x21 0xF9)
如果(数据[0x30D]==0x21&&data[0x30E]==0xF9)
数据[0x313]=(字节)白索引;
}
}
//现在字节数组包含一个透明颜色为白色的Gif图像

谢谢您的回答。事实上,Windows7GIF编码器没有任何问题。只是,它的行为与之前的编码器不同:它生成不同(但正确)的调色板。由于此调色板已更改,我的代码不再工作。我想知道是否有一种快速的方法来检测调色板中白色的索引是什么,这样我就可以将此索引设置为透明色。