Perché mi appare questa generica, errore non descritto in GDI + quando si cerca di salvare un PNG?
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) peroInfo(4)
(png)
Ci sono più cose che ho bisogno di modificare per ottenere questa routine per generare correttamente il PNG?
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.