2008-10-09 46 views
10

我试图从.aspx页面返回一个透明的GIF在网页中显示。我试图让图像具有透明度,但我只是不断让黑色成为图像应该透明的地方。如何使用System.Drawing绘制透明图像?

有谁知道我在做什么错?

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

我删除了我的帖子,所以它不会混乱这个了。 – mattlant 2008-10-09 23:34:23

回答

5

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

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

6

是的,正如杰罗姆所说,没有办法用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 
4

这是可能但不容易
如果你能在你的项目中使用不安全的代码,有几个方法使用指针来翻转颜色表并使透明度工作。

鲍勃鲍威尔的示例表格应用程序可在这里获得http://www.bobpowell.net/giftransparency.htm。几年前,我在网络处理程序上使用了这种方法的一个变体,每个月它的浏览次数大约是1000万次,而且看起来效果不错。

如果您只使用有限的颜色托盘,则可以将颜色表处理降低到所需的颜色(不记得我是如何做到的......)。

这就是说,png是一个更容易的度量crapload。

2

这里有一些代码在位图中有一个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égoireLafortune