Coded – Web Development and Programming Blog

C#, ASP.NET, Google, Remoting, AJAX, Silverlight, Web Development

Generating a transparent GIF image using C#

Posted in ASP.NET, C#, Web Programming by Andrei Alecu on the August 28th, 2007

Problem:

There is apparently no easy way to generate a transparent GIF image using the .NET framework. Microsoft provided a method in the Bitmap class called MakeTransparent() but it doesn’t work for GIFs, it only seems to work for PNGs.

To create a transparent GIF you need to recreate the color table of the image using Imaging APIs, as detailed in this KB article . Unfortunately, this can be pretty slow for an ASP.NET Web application, and it has a lot of overhead, so I needed an alternative.

Solution:

The alternative is to alter the color table directly using the GIF specification. To implement this, I needed to save the non-transparent GIF to a MemoryStream, and then go through the binary data, updating the color table with the new transparency bits.

The original code for this function is not my own, I have found it somewhere on the Internet and modified it. Unfortunately I can’t remember where I found it, so I can’t give credit, but if you know the original author please add a comment.

Source:

Download ASP.NET GIF Transparency Demo WebForm
[tags]C#, GIF, Transparent GIF, ASP.NET, Bitmap, System.Graphics[/tags]

Bookmark on del.icio.us

17 Responses to 'Generating a transparent GIF image using C#'

Subscribe to comments with RSS

  1. Vladimir said,

    on October 18th, 2007 at 5:56 am

    Hi Andrei,

    Great Posting thank you very much for sharing this info.
    Although the code published has some syntaxes problems and a extra almost at the beginning.
    Referring to this topic, I think you are generating GIFs because you want to display transparent images on the a browser and IE6 is not a good player with PNG.
    An alternative would be to let .NET generate a PNG8 that’s well accepted by IE4 onwards!
    But I couldn’t find a why to make the .NET framework do it, do you know if that’s possible?

    Best regards,

    Vladimir

  2. Csiga said,

    on February 6th, 2008 at 12:16 pm

    Dear Andrei,

    This is excellent! You save me a lot of time, not to mention those hours what I spent searching for such a "converter". I’m developing a web application, where I use a lot of transparent images, but I have to use the png format (because of the Graphics.FromImage function – isn’t able to populate Graphics object from image with indexed format, like gif). Of course, our wonderful browser (let’s call it "ie6.0"), doesn’t support transparent png, only with alphaimageloader, but it isn’t so fast. With this function, I can create gif-s for mozilla and for explorer too from the png files I create. This is the solution for me! So, you rock! :)

    Thanks a lot!

    Best regards,
    Csiga

  3. Kim said,

    on March 7th, 2008 at 6:56 am

    Dear Andrei,

    Thank you very much! Your article give me a very usedly help.
    In order to resovle this issue,I had searched all forums,BBS,Tech. Blog in China almost,but can’t get a best solution yet,so much as I had make a decision to give up it.

    Thanks!

    Best regards,
    Kim

  4. Joe said,

    on May 25th, 2008 at 4:54 pm

    Could someone please post the code without any syntax errors.
    Thanks

  5. janeks said,

    on June 12th, 2008 at 5:38 pm

    I’m wondering wouldn’t be easer to convert GIF to PNG, then use .NET function foradding transparency, then convert PNG back to the GIF?

    Or it’s not working?

  6. victor said,

    on July 3rd, 2008 at 1:28 pm

    Here is the code w/o syntax errors.
    //
    ///
    /// Returns a transparent background GIF image from the specified Bitmap.
    ///
    /// The Bitmap to make transparent.
    /// The Color to make transparent.
    /// New Bitmap containing a transparent background 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] & 0×80) > 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] != 0×21) 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] |= 0×01;
    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);
    }
    //

  7. janos said,

    on October 23rd, 2008 at 12:14 pm

    i think the orginial author of the code can be found here:

    http://www.ben-rush.net/blog/PermaLink.aspx?guid=103ed74d-c808-47ba-b82d-6e9367714b3e&dotnet=consultant

  8. Dave said,

    on October 24th, 2008 at 12:05 pm

    Thanks for this! Just what I was looking for. Nice job to whomever created it.

    A slight change is required if a color exists twice within a gif color map. I changed the declaration of the transparent index to :

    byte? transparentIdx = null;

    Then altered the for loop that searched for the index:

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

    Finally, I changed the assignment at the bottom to convert the nullable index to a standard byte.

    if (count == 4)
    {
    buf[0] |= 0×01;
    buf[3] = (byte)transparentIdx;
    }

    Again, thanks!

  9. Salman said,

    on February 13th, 2009 at 1:14 am

    I have had success in creating transparent GIFs in ASP.NET. In my code sample I added a hack for forcing GIF transparency and work around the .NET limitation of a pre-defined non-transparent palette. Have a look at this article:

    http://911-need-code-help.blogspot.com/2009/02/create-text-images-on-fly-with-aspnet.html

  10. Reader said,

    on August 11th, 2009 at 12:47 pm

    Complete code is useless, and only usefull for those whom have a fix requirements.

  11. O_O said,

    on June 1st, 2010 at 5:21 pm

    this code doesn’t work. it doesn’t pick a transparent color in any way that uses at least a bit inteligence, so it’s quite useless… .

  12. O_O said,

    on June 1st, 2010 at 6:18 pm

    to add:
    this algorithm recognizes only colors with the same rgb.

  13. coder said,

    on August 13th, 2010 at 7:12 pm

    Thanks again, the source code you posted is very helpful! :-)


  14. on August 26th, 2010 at 7:21 am

    Thanks for such a great post and the review, I am totally impressed! Keep stuff like this coming.

  15. gameladen said,

    on August 30th, 2010 at 1:43 am

    very cool post


  16. on August 30th, 2010 at 10:01 pm

    Perhaps this is one of the most interesting blogs that I have ever seen. Interesting article, Funny comment. Keep it up!

  17. Carl said,

    on August 31st, 2010 at 8:41 am

    I didn’t know about this. Wow, it has been an eye-opener. So glad to have stumbled upon this.

Leave a Reply