我有一个功能,可以在预先指定的位置动态添加文本到图像.最初我用jpegs做了它,它正在工作.我切换到PNG,因此图像的质量会更好,因为原始的jpegs有点像素.无论如何,这是我的代码.它执行到oBitmap.Save()
,然后死于"GDI +中发生了一般错误".
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest context.Response.ContentType = "image/png" context.Response.Clear() context.Response.BufferOutput = True Try Dim oText As String = context.Server.HtmlDecode(context.Request.QueryString("t")) If String.IsNullOrEmpty(oText) Then oText = "Placeholder" Dim oPType As String = context.Server.HtmlDecode(context.Request.QueryString("p")) If String.IsNullOrEmpty(oPType) Then oPType = "none" Dim imgPath As String = "" Select Case oPType Case "c" imgPath = "img/banner_green.png" Case "m" imgPath = "img/banner_blue.png" Case Else Throw New Exception("no ptype") End Select Dim oBitmap As Bitmap = New Bitmap(context.Server.MapPath(imgPath)) Dim oGraphic As Graphics = Graphics.FromImage(oBitmap) Dim frontColorBrush As New SolidBrush(Color.White) Dim oFont As New Font(FONT_NAME, 30) Dim oInfo() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders Dim oEncoderParams As New EncoderParameters(2) Dim xOffset As Single = Math.Round((oBitmap.Height - oFont.Height) / 2, MidpointRounding.ToEven) Dim oPoint As New PointF(275.0F, xOffset + 10) oEncoderParams.Param(0) = New EncoderParameter(Encoder.Quality, 100L) oEncoderParams.Param(1) = New EncoderParameter(Encoder.ColorDepth,8L) oGraphic.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias oGraphic.DrawString(oText, oFont, frontColorBrush, oPoint) oBitmap.Save(context.Response.OutputStream, oInfo(4), oEncoderParams) context.Response.Output.Write(oBitmap) oFont.Dispose() oGraphic.Dispose() oBitmap.Dispose() context.Response.Flush() Catch ex As Exception End Try End Sub
我对jpeg版本所做的唯一更改是:
context.Response.ContentType = "image/jpeg"
变成 "image/png"
将基本图像(img/banner_green.jpg
,img/banner_blue.jpg
)更改为.png
添加了指定颜色深度的第二个编码参数
改为oInfo(1)
(jpeg)为oInfo(4)
(png)
我需要调整更多的东西才能使这个例程正确生成PNG吗?
根据这篇文章,Bitmap.Save需要一个可搜索的流来保存为PNG,HttpResponse.OutputStream不是.您必须先将图像保存到MemoryStream中,然后将其内容复制到Response.OutputStream,如:
Dim tempStream as New MemoryStream oBitmap.Save(tempStream, ImageFormat.Png, oEncoderParams) Response.OutputStream.Write(tempStream.ToArray(), 0, tempStream.Length)
还要注意这一行
context.Response.Output.Write(oBitmap)
做一些不同于你可能期待的事情.HttpResponse.Output
是一个TextWriter,你在这里使用的重载TextWriter.Write(object)
只会在对象上调用ToString并将结果写入流中,在这种情况下会导致将"System.Drawing.Bitmap"写入输出.