Pourquoi ai-je cette erreur générique, non classées dans GDI + lorsque vous essayez d'enregistrer un PNG?
Question
J'ai une fonction qui ajoute dynamiquement texte à une image dans un endroit predesignated. Au départ, je l'ai fait avec jpegs, et cela fonctionnait. Je suis passé à PNG de sorte que les images seraient de meilleure qualité, comme les originaux étaient jpegs genre de pixely. Quoi qu'il en soit, voici mon code. Il exécute jusqu'à la oBitmap.Save()
, puis meurt avec « Une erreur générale a produite dans 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
Les seules modifications apportées à ce que je de la version jpeg sont:
-
context.Response.ContentType = "image/jpeg"
changé à"image/png"
- images de base (changé
img/banner_green.jpg
,img/banner_blue.jpg
) à.png
- a ajouté le second paramètre de codage indiquant la profondeur de couleur
- changé
oInfo(1)
(jpeg) àoInfo(4)
(.png)
Y at-il plus de choses que je dois modifier pour obtenir cette routine pour générer correctement le PNG?
La solution
Selon ce poste , Bitmap.Save nécessite un flux adressable pour enregistrer en tant que PNG, qui HttpResponse.OutputStream est pas. Vous devez enregistrer l'image dans un MemoryStream d'abord, puis copier le contenu de celui-ci à Response.OutputStream, comme:
Dim tempStream as New MemoryStream
oBitmap.Save(tempStream, ImageFormat.Png, oEncoderParams)
Response.OutputStream.Write(tempStream.ToArray(), 0, tempStream.Length)
Notez également que la ligne
context.Response.Output.Write(oBitmap)
fait quelque chose de différent alors ce que vous attendiez probablement. Est un TextWriter HttpResponse.Output
et la surcharge que vous utilisez ici, appelera juste TextWriter.Write(object)
ToString sur l'objet et écrire les résultats dans le flux, ce qui, dans ce cas, les résultats par écrit « System.Drawing.Bitmap » à la sortie.
Autres conseils
Vous disposer du bitmap avant vous rincer la réponse? Essayez feuilletant ce autour. En outre, il semble que vous écrivez le bitmap au courant deux fois. Je ne sais pas pourquoi vous faites cela. Enregistrer l'image dans le flux de sortie ou utiliser la méthode Write de l'objet Response, mais pas les deux.