代码之家  ›  专栏  ›  技术社区  ›  Chris Pietschmann

如何使用System.Drawing绘制透明图像?

  •  10
  • Chris Pietschmann  · 技术社区  · 17 年前

    我试图从.aspx页面返回透明的gif,以便在网页中显示。我试图让图像具有透明度,但我只是不断地变黑,因为图像应该是透明的。

    有人知道我做错了什么吗?

    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
    
    4 回复  |  直到 16 年前
        1
  •  5
  •   Jérôme Laban    17 年前

    不幸的是,没有一种简单的方法可以使用位图对象创建透明的GIF。(见 this KB article )

    您也可以使用PNG格式,该格式支持对所用代码的透明度。

        2
  •  6
  •   Chris Pietschmann    17 年前

    是的,正如杰罗姆所说,无论如何都不能用位图对象创建透明的GIF。废话!

    好吧,不管怎样,我修改了我的代码来生成一个PNG,并且一切都按预期工作。

    有一个小的工作我确实需要做,因为你不能直接写PNG的输出流。我需要将png写入一个memorystream,然后将其写入输出流。

    下面是我实现的最终代码:

    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
    
        3
  •  4
  •   seanb    17 年前

    它是 可能的 , 但不容易
    如果您能够在项目中使用不安全的代码,那么有几种方法可以使用指针来撕开颜色表并使透明度起作用。

    Bob Powell的示例表单应用程序可在此处获得 http://www.bobpowell.net/giftransparency.htm .几年前,我在一个Web处理程序上使用了这种方法的一个变体,它每月受到大约1000万次的攻击,而且似乎工作得很好。

    如果您只使用有限的颜色托盘,您可以将颜色表处理减少到您需要的颜色(不记得我是如何做到的…)。

    也就是说,巴布亚新几内亚是一个更容易的公制克拉普洛德。

        4
  •  2
  •   Grégoire Lafortune    16 年前

    这里有一些代码可以在位图中转换GIF(其中已经具有透明度),然后用它的透明度正确显示。

    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);
    

    祝你好运!

    gr_)Goire Lafuture

    推荐文章