Por que estou recebendo este erro genérico, não descrita em GDI + ao tentar salvar um PNG?

StackOverflow https://stackoverflow.com/questions/511579

  •  21-08-2019
  •  | 
  •  

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) para oInfo(4) (png)

Existem mais coisas que eu preciso ajustar para conseguir essa rotina para gerar corretamente o PNG?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top