ASP.NET 透明 GIF






2.23/5 (4投票s)
使用 ASP.NET 和 C# 将透明 GIF 直接写入输出流。
引言
将图像写入 HTTP 响应的输出流是一项简单的任务。将透明 GIF 写入输出流则不然。原因是 GDI+ 处理程序用于将图像数据保存到输出流。这是一种解决方法。
背景
网站管理员需要一些很酷的工具来维护他们的网站并跟踪以使他们的业务更好。这就是为什么许多这些网站管理员运行像 Google Analytics 这样的工具来跟踪用户行为并跟踪冲浪者来自哪里(例如,通过 Google 的搜索字符串、引荐来源、自然输入等)。
由于某些原因,我的一个客户对使用 Google Analytics 并不满意,原因有两个主要原因
- 使用 JavaScript 违反了他们的政策。
- Google Analytics 获取的数据是 Google Inc. 的财产。
因此,他们需要一个无需 JavaScript 即可运行并满足其需求的小而简单的跟踪解决方案。
Using the Code
要跟踪引荐来源,您需要有一个可以被请求的应用程序。由于企业设计问题,请求的响应应该是一个透明的图像 - 所以一个透明的 GIF 正是我需要的。
我准备了一个透明的 GIF 并尝试了以下操作
Bitmap bm = new Bitmap(Server.MapPath("transparent.gif"));
Response.ContentType = "image/gif";
bm.Save(Response.OutputStream, ImageFormat.Gif);
bm.Dispose();
Response.Flush();
好吧,这不起作用。传递到输出流的图像是黑色的。然后我稍微尝试了一下
bm.MakeTransparent(Color.Transparent);
但这也不起作用。我的想法是我的准备好的 GIF 坏了,所以我创建了一个干净的黑色 GIF 并尝试使用 MakeTransparent(Color.Black)
,但没有成功。
解决方案
System.Drawing.Image _gifImage;
_gifImage = System.Drawing.Image.FromFile(Server.MapPath("white.JPG"));
Bitmap bm = new Bitmap(_gifImage.Width, _gifImage.Height,
PixelFormat.Format8bppIndexed);
// Get the palette from the bitmap
ColorPalette pal = bm.Palette;
// Set Alpha to 0
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);
}
// assign palette
bm.Palette = pal;
//to copy the bitmap data we need to lock the source &
//destination bits
BitmapData src = ((Bitmap)_gifImage).LockBits(new Rectangle
(0, 0, _gifImage.Width, _gifImage.Height), ImageLockMode.ReadOnly,
_gifImage.PixelFormat);
BitmapData dst = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height),
ImageLockMode.WriteOnly, bm.PixelFormat);
//finished, unlock the bits
((Bitmap)_gifImage).UnlockBits(src);
bm.UnlockBits(dst);
//Set Response Type to "image/gif"
Response.ContentType = "image/gif";
//Writing the gif directly into the Output-Stream
bm.Save(Response.OutputStream, ImageFormat.Gif);
//cleaning up
bm.Dispose();
_gifImage.Dispose();
//Send output stream
Response.Flush();
简而言之,我们正在为我们的 GIF 创建一个新的颜色调色板。然后,我们将所有 Alpha 值更改为零 - GIF 编码器现在将为 Alpha == 0 的每个条目编码透明颜色。
关注点
Bitmap.Save()
方法在将图像传递给 GIF 编码器之前,将 GIF 的格式提升为 32 bpp。 GIF 编码器将其颜色减少为 256 色的颜色表。当动态生成的图像格式为 8 bpp 时,GIF 编码器只将它的调色板条目编码成可能的最小 GIF 颜色表。而这正是这里的问题所在。
链接和资源
- 关于透明 GIF 的 GDI+ 常见问题解答:http://www.bobpowell.net/giftransparency.htm。
- MSDN 关于调色板操作:http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q319061。
历史
- 2007/04/09: 初始发布。