¿Por qué recibo este error genérico, que no se nota en GDI + cuando intenta guardar un archivo PNG?

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

  •  21-08-2019
  •  | 
  •  

Pregunta

Tengo una función que añade dinámicamente texto a una imagen en un lugar previamente designado. Originalmente lo hice con archivos JPEG, y que estaba trabajando. Cambié a PNG para las imágenes serían de mejor calidad, ya que los archivos JPEG originales eran una especie de pixely. De todos modos, aquí está mi código. Ejecuta hasta el oBitmap.Save(), luego muere con "un error general se ha producido en 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

Los únicos cambios que hice a este respecto a la versión JPEG son:

  • context.Response.ContentType = "image/jpeg" cambió a "image/png"
  • Imágenes cambiado de bases (img/banner_green.jpg, img/banner_blue.jpg) a .png
  • añade el segundo parámetro de codificación que especifica la profundidad de color
  • cambiado oInfo(1) (JPEG) a oInfo(4) (png)

¿Hay más cosas que tengo que pellizcar para obtener esta rutina para generar correctamente el PNG?

¿Fue útil?

Solución

Según este post , Bitmap.Save requiere una corriente seekable guardar como PNG, que HttpResponse.OutputStream no lo es. Vas a tener que guardar la imagen en un MemoryStream primero, y luego copiar el contenido del mismo a Response.OutputStream, como:

Dim tempStream as New MemoryStream
oBitmap.Save(tempStream, ImageFormat.Png, oEncoderParams)
Response.OutputStream.Write(tempStream.ToArray(), 0, tempStream.Length)

Tenga en cuenta también que la línea

context.Response.Output.Write(oBitmap)

hace algo diferente de lo que es probable que esté esperando. HttpResponse.Output es un TextWriter, y la sobrecarga se utiliza aquí, se acaba de llamar TextWriter.Write(object) ToString en el objeto y escribir los resultados en la corriente, lo que en este caso los resultados en la escritura "System.Drawing.Bitmap" a la salida.

Otros consejos

Esta disponer del mapa de bits antes de que esté lavado de la Respuesta? Trate de mover de un tirón que alrededor. Además, parece que se está escribiendo el mapa de bits en la secuencia dos veces. No estoy seguro de por qué estás haciendo eso. Guardar el mapa de bits en el flujo de salida o utilizar el método Write del objeto Response, pero no ambos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top