2008-10-09 11 views
10

Ich versuche, ein transparentes GIF von einer ASPX-Seite zur Anzeige auf einer Webseite zurückzugeben. Ich versuche, das Bild transparent zu machen, aber ich bekomme einfach Schwarz, wo das Bild Transparent sein soll.Wie zeichnen Sie ein transparentes Bild mit System.Drawing?

Weiß jemand, was ich falsch mache?

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 
+0

entfernte ich meinen Beitrag, damit es diese bis Krempel tut. – mattlant

Antwort

5

Leider gibt es keine einfache Möglichkeit, ein transparentes GIF mit einem Bitmap-Objekt zu erstellen. (Siehe this KB article)

Sie können auch das PNG-Format verwenden, das Transparenz mit dem von Ihnen verwendeten Code unterstützt.

6

Ja, wie Jerome sagte, gibt es sowieso keine transparenten GIFs mit einem Bitmap-Objekt zu erstellen. Mist!

Nun, jedenfalls habe ich meinen Code geändert, um ein PNG zu generieren und alles funktioniert wie erwartet.

Es gibt eine kleine Arbeit, die ich tun musste, da Sie PNGs nicht direkt in den OutputStream schreiben können. Ich musste das PNG in einen MemoryStream schreiben und das dann in den OutputStream schreiben.

Hier ist der endgültige Code für meine Implementierung:

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 
4

Es ist möglich, aber nicht einfach
Wenn Sie in der Lage sind in Ihrem Projekt unsicheren Code zu verwenden, gibt es ein paar Methoden Verwenden Sie Zeiger, um die Farbtabelle zu durchforsten und die Transparenz zu gewährleisten.

Eine Beispielform-App von Bob Powell ist hier verfügbar http://www.bobpowell.net/giftransparency.htm. Ich habe vor einigen Jahren eine Variation dieser Methode auf einem Web-Handler verwendet, die ungefähr 10 Millionen Mal pro Monat gelaufen ist, und es schien gut zu funktionieren.

Wenn Sie nur eine begrenzte Farbpalette verwenden, können Sie die Verarbeitung der Farbtabelle auf die Farben reduzieren, die Sie benötigen (ich kann mich nicht genau daran erinnern, wie ich das gemacht habe ...).

Das heißt, png ist eine metrische crapload einfacher.

2

hier ist ein Code, um ein gif (das bereits Transparenz darin haben) transformiert (angenommen, dass Sie die Größe ändern wollen) in Bitmap und kann dann mit seiner Transparenz richtig angezeigt werden.

imagePath = System.Web.HttpContext.Current.Request.MapPath(libraryPath + reqImageFile); 
System.Drawing.Image image = null; 
Bitmap resizedImage = null; 

if (reqWidth == 0) { reqWidth = image.Width; } 
if (reqHeight == 0) { reqHeight = image.Height; } 
image = System.Drawing.Image.FromFile(imagePath); 
reqWidth = image.Width; 
reqHeight = image.Height; 

//here is the transparency 'special' treatment 
resizedImage = new Bitmap(reqWidth, reqHeight, PixelFormat.Format8bppIndexed); 
ColorPalette pal = resizedImage.Palette; 
for (int i = 0; i < pal.Entries.Length; i++) 
{ 
     Color col = pal.Entries[i]; 
     pal.Entries[i] = Color.FromArgb(0, col.R, col.G, col.B); 
} 
resizedImage.Palette = pal; 
BitmapData src = ((Bitmap)image).LockBits(new Rectangle(0, 0, reqWidth, reqHeight), ImageLockMode.ReadOnly, image.PixelFormat); 
BitmapData dst = resizedImage.LockBits(new Rectangle(0, 0, resizedImage.Width, resizedImage.Height), 
ImageLockMode.WriteOnly, resizedImage.PixelFormat); 
((Bitmap)image).UnlockBits(src); 
resizedImage.UnlockBits(dst); 

Viel Glück!

Grégoire Lafortune