tags:

views:

124

answers:

2

Before Windows 7 (and the new image codecs: WIC) I used the following (very fast but dirty) method to create a Gif encoded image with white as the transparent color:

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

This method worked because .NET used to encode Gif with a standard palette in which index 255 was the color white.

In Windows 7 however this method is not working anymore. It seems the standard palette is changed and now the index 251 is the color white. I am however not sure. Maybe the new Gif encoder is dynamically generating a palette based on the used colors?

My question: Does anybody have insight in the new Gif encoder of Windows 7 and what would be a good and fast way to make the color white transparent?

A: 

Are you sure this is a Windows 7 issue and not a problem elsewhere with your code?

The GIF specification suggests that any index could be used for transparency. You may want to check your image to ensure that the appropriate bit enabling transparency is set on. If it isn't, then the palette index you've selected will be ignored.

Jeremy McGee
Thanks for your answer. There is in fact nothing wrong with the Windows 7 Gif encoder. Only, it is behaving differently compared to the previous encoder: it produces a different (but correct) palette. Because this palette has changed, my code is not working anymore. I am wondering if there is a fast way to detect what the index is of the color white in the palette so I can set this index as the transparent color.
Corne
+1  A: 

I have found a better way to set the color white as the transparent color for a gif encoded image. It seems to work for Gif's that are encoded by both GDI+ and WIC (Windows 7) encoders. The following code searches for the index of the color white in the Global Image Table of the Gif and uses this index to set the transparent color in the Graphic Control Extension block.

 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
Corne