Perché mi appare questa generica, errore non descritto in GDI + quando si cerca di salvare un PNG?

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

  •  21-08-2019
  •  | 
  •  

Domanda

Ho una funzione che aggiunge in modo dinamico il testo a un'immagine in un luogo prestabilito. Originariamente ho fatto con i file JPEG, e lavoravo. Sono passato in PNG in modo che le immagini sarebbero una migliore qualità, come i file JPEG originali erano tipo di pixely. Ad ogni modo, ecco il mio codice. Esegue fino al oBitmap.Save(), poi muore con "un errore generale si è verificato in 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

Gli unici cambiamenti che ho fatto per questo dalla versione jpeg sono:

  • context.Response.ContentType = "image/jpeg" modificato in "image/png"
  • immagini di base modificato (img/banner_green.jpg, img/banner_blue.jpg) a .png
  • aggiunto il secondo parametro di codifica specifica profondità di colore
  • cambiato oInfo(1) (jpeg) per oInfo(4) (png)

Ci sono più cose che ho bisogno di modificare per ottenere questa routine per generare correttamente il PNG?

È stato utile?

Soluzione

questo post , Bitmap.Save richiede un flusso ricercabile salvare come PNG, che HttpResponse.OutputStream non lo è. Dovrete salvare l'immagine in un MemoryStream prima, e poi copiare il contenuto di esso per Response.OutputStream, come:

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

Si noti inoltre che la riga

context.Response.Output.Write(oBitmap)

fa qualcosa di diverso, allora ciò che si sta probabilmente aspettate. HttpResponse.Output è un TextWriter, e del sovraccarico si usa qui, TextWriter.Write(object) sarà solo chiamare ToString sull'oggetto e scrivere i risultati nel flusso, ciò che in questo caso i risultati per iscritto "System.Drawing.Bitmap" per l'uscita.

Altri suggerimenti

Stai smaltimento del bitmap prima che tu sia il lavaggio del Response? Provare lanciando che circa. Inoltre, sembra che si sta scrivendo la bitmap al flusso due volte. Io non so perché si sta facendo questo. Salvare il bitmap nel flusso di output o utilizzare il metodo Write dell'oggetto Response, ma non entrambi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top