GDI+ で PNG を保存しようとすると、この一般的で説明のないエラーが発生するのはなぜですか?

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

  •  21-08-2019
  •  | 
  •  

質問

画像の事前に指定した場所にテキストを動的に追加する機能があります。もともとjpegでやっていたのですが、うまくいきました。元の JPEG はピクセル状だったので、画像の品質を向上させるために PNG に切り替えました。とにかく、これが私のコードです。まで実行されます。 oBitmap.Save(), 、その後、「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

JPEG バージョンからこれに加えた唯一の変更は次のとおりです。

  • context.Response.ContentType = "image/jpeg" に変更されました "image/png"
  • 基本イメージを変更しました (img/banner_green.jpg, img/banner_blue.jpg) に .png
  • 色深度を指定する 2 番目のエンコード パラメータを追加しました
  • かわった oInfo(1) (jpeg) に oInfo(4) (png)

このルーチンで PNG を適切に生成するには、さらに調整する必要があることがありますか?

役に立ちましたか?

解決

この記事のによると、Bitmap.Saveはシーク可能なストリームが必要ですHttpResponse.OutputStreamではないPNGとして保存します。

:最初のMemoryStreamに画像を保存し、Response.OutputStreamへの内容をコピー、のようにする必要があります
Dim tempStream as New MemoryStream
oBitmap.Save(tempStream, ImageFormat.Png, oEncoderParams)
Response.OutputStream.Write(tempStream.ToArray(), 0, tempStream.Length)

は、また、行

ことに注意してください
context.Response.Output.Write(oBitmap)

あなたはおそらく期待しているものを、その後別の何かをします。 HttpResponse.OutputがしたTextWriterで、ここで使用する過負荷は、TextWriter.Write(object)だけでオブジェクトのToStringメソッドを呼び出すと、ストリームに結果を書き込みます、どのようなこの場合の出力への書き込み「System.Drawing.Bitmapを」の結果ます。

他のヒント

あなたが応答をフラッシュしている前に、

あなたは、ビットマップを処分していますか?その周りを反転してみてください。あなたが二回ストリームにビットマップを書いているようにも、それが見えます。私は、なぜあなたはそれをやっているかわかりません。出力ストリームにビットマップを保存するか、ResponseオブジェクトのWriteメソッドを使用し、両方はできません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top