Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you Draw Transparent Image using System.Drawing?

I'm trying to return a transparent GIF from an .aspx page for display within a web page. I am trying to get the image to have transparency, but I just keep getting Black being where the image should be Transparent.

Does anyone know what I'm doing wrong?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
  Handles Me.Load
    '' Change the response headers to output a GIF image.
    Response.Clear()
    Response.ContentType = "image/gif"

    Dim width = 110
    Dim height = width

    '' Create a new 32-bit bitmap image
    Dim b = New Bitmap(width, height)

    '' Create Grahpics object for drawing
    Dim g = Graphics.FromImage(b)

    Dim rect = New Rectangle(0, 0, width - 1, height - 1)

    '' Fill in with Transparent
    Dim tbrush = New System.Drawing.SolidBrush(Color.Transparent)
    g.FillRectangle(tbrush, rect)

    '' Draw Circle Border
    Dim bPen = Pens.Red
    g.DrawPie(bPen, rect, 0, 365)

    '' Fill in Circle
    Dim cbrush = New SolidBrush(Color.LightBlue)
    g.FillPie(cbrush, rect, 0, 365)


    '' Clean up
    g.Flush()
    g.Dispose()

    '' Make Transparent
    b.MakeTransparent()

    b.Save(Response.OutputStream, Imaging.ImageFormat.Gif)
    Response.Flush()
    Response.End()
End Sub
like image 891
Chris Pietschmann Avatar asked Oct 09 '08 22:10

Chris Pietschmann


3 Answers

Yes, as Jerome stated, there isn't anyway to create transparent GIF's using a Bitmap object. Crap!

Well, anyway, I changed my code to generate a PNG and all works as expected.

There is one small work around I did need to do since you cannot write PNG's directly to the OutputStream. I needed to write the PNG to a MemoryStream, and then write that out to the OutputStream.

Here's the final code for my implementation:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
  Handles Me.Load
    '' Change the response headers to output a JPEG image.
    Response.Clear()
    Response.ContentType = "image/png"

    Dim width = 11
    Dim height = width

    '' Create a new 32-bit bitmap image
    Dim b = New Bitmap(width, height)

    '' Create Grahpics object for drawing
    Dim g = Graphics.FromImage(b)

    '' Fill the image with a color to be made Transparent after drawing is finished.
    g.Clear(Color.Gray)

    '' Get rectangle where the Circle will be drawn
    Dim rect = New Rectangle(0, 0, width - 1, height - 1)

    '' Draw Circle Border
    Dim bPen = Pens.Black
    g.DrawPie(bPen, rect, 0, 365)

    '' Fill in Circle
    Dim cbrush = New SolidBrush(Color.Red)
    g.FillPie(cbrush, rect, 0, 365)

    '' Clean up
    g.Flush()
    g.Dispose()

    '' Make Transparent
    b.MakeTransparent(Color.Gray)

    '' Write PNG to Memory Stream then write to OutputStream
    Dim ms = New MemoryStream()
    b.Save(ms, Imaging.ImageFormat.Png)
    ms.WriteTo(Response.OutputStream)

    Response.Flush()
    Response.End()
End Sub
like image 138
Chris Pietschmann Avatar answered Nov 15 '22 18:11

Chris Pietschmann


Unfortunately, there is no easy way to create a transparent Gif using a Bitmap object. (See this KB article)

You can alternatively use the PNG format that supports transparency with the code you are using.

like image 27
Jérôme Laban Avatar answered Nov 15 '22 19:11

Jérôme Laban


It is possible, but not easy.

If you are able to use unsafe code in your project, there are a few methods to use pointers to rip through the colour table and make the transparency work.

A sample forms app by Bob Powell is available at https://web.archive.org/web/20141227173018/http://bobpowell.net/giftransparency.aspx. I used a variation on this method in a web handler, and it seemed to work fine.

If you are only using a limited colour palette, you can reduce the colour table processing to just the colours you need (can't remember exactly how I did that...).

That being said, png is substantially easier.

like image 34
seanb Avatar answered Nov 15 '22 17:11

seanb