【问题标题】:How do you Draw Transparent Image using System.Drawing?如何使用 System.Drawing 绘制透明图像?
【发布时间】:2010-09-16 09:45:07
【问题描述】:

我正在尝试从 .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

【问题讨论】:

  • 我删除了我的帖子,所以它不会弄乱它。

标签: asp.net transparency gif system.drawing


【解决方案1】:

是的,正如 Jerome 所说,无论如何都无法使用 Bitmap 对象创建透明 GIF。废话!

好吧,无论如何,我更改了我的代码以生成 PNG,并且一切都按预期工作。

我确实需要做一项小工作,因为您不能将 PNG 直接写入 OutputStream。我需要将 PNG 写入 MemoryStream,然后将其写入 OutputStream。

这是我的实现的最终代码:

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

【讨论】:

    【解决方案2】:

    不幸的是,没有简单的方法可以使用 Bitmap 对象创建透明 Gif。 (见this KB article

    您也可以将支持透明度的 PNG 格式与您正在使用的代码一起使用。

    【讨论】:

      【解决方案3】:

      有可能,但不容易

      如果您能够在您的项目中使用不安全的代码,有一些方法可以使用指针来翻阅颜色表并使透明度起作用。

      Bob Powell 的示例表单应用程序可通过https://web.archive.org/web/20141227173018/http://bobpowell.net/giftransparency.aspx 获取。我在 web 处理程序中使用了这种方法的变体,它似乎工作正常。

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

      话虽如此,png 要容易得多。

      【讨论】:

        【解决方案4】:

        这里有一些代码可以在位图中转换(假设你想调整它的大小)的 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 Lafortune

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-16
          • 1970-01-01
          • 1970-01-01
          • 2011-02-24
          • 1970-01-01
          • 1970-01-01
          • 2014-03-13
          • 2020-10-24
          相关资源
          最近更新 更多