Por que estou recebendo este erro genérico, não descrita em GDI + ao tentar salvar um PNG?
Pergunta
Eu tenho uma função que adiciona dinamicamente texto a uma imagem em um local predesignated. Originalmente eu fiz isso com jpegs, e ele estava funcionando. Mudei para PNG para que as imagens seria melhor qualidade, como os jpegs originais eram uma espécie de pixely. De qualquer forma, aqui está o meu código. Ele executa até o oBitmap.Save()
, em seguida, morre com "Erro Um Geral ocorreu em 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
As únicas mudanças que eu fiz para isso a partir da versão jpeg são:
-
context.Response.ContentType = "image/jpeg"
alterado para"image/png"
- imagens alteradas base (
img/banner_green.jpg
,img/banner_blue.jpg
) para.png
- acrescentou o segundo parâmetro de codificação especificando profundidade de cor
- mudou
oInfo(1)
(jpeg) paraoInfo(4)
(png)
Existem mais coisas que eu preciso ajustar para conseguir essa rotina para gerar corretamente o PNG?
Solução
De acordo com a este post , Bitmap.Save requer um fluxo pesquisável para salvar como PNG, que HttpResponse.OutputStream não é. Você vai ter que salvar a imagem em um MemoryStream primeiro, e depois copiar o conteúdo para Response.OutputStream, como:
Dim tempStream as New MemoryStream
oBitmap.Save(tempStream, ImageFormat.Png, oEncoderParams)
Response.OutputStream.Write(tempStream.ToArray(), 0, tempStream.Length)
Além disso, observe que a linha
context.Response.Output.Write(oBitmap)
faz algo diferente, então o que você está provavelmente esperando. HttpResponse.Output
é um TextWriter, ea sobrecarga você usa aqui, TextWriter.Write(object)
só vai chamar ToString no objeto e escrever os resultados para a corrente, o que neste caso os resultados por escrito "System.Drawing.Bitmap" para a saída.
Outras dicas
Você está descartar o bitmap antes que você está liberando a resposta? Tente lançando que ao redor. Além disso, parece que você está escrevendo o bitmap para o fluxo de duas vezes. Eu não sei por que você está fazendo isso. Salvar o bitmap para o fluxo de saída ou usar o método Write do objeto Response, mas não ambos.