C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

新規作成したBitmapのSaveメソッドでエラーが発生する

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■82898 / inTopicNo.1)  新規作成したBitmapのSaveメソッドでエラーが発生する
  
□投稿者/ はるた (1回)-(2017/02/17(Fri) 21:50:34)

分類:[.NET 全般] 

VB.net .net Framework 3.5.1 でWebサービスを作成しています。

指定した文字列からPNGファイルを作成するプログラムを作成したのですが、
普段動作していたものが急にエラーを出力するようになります。
一度エラーが発生するとIISのアプリケーションプールをリサイクルするまでは何度実行してもエラーとなります。

既存ファイルを編集して上書きする場合に同じエラーが発生する情報は見かけるのですが、
新規作成しているため違う原因だと考えています。

考えられる原因を教えて下さい。

<コード>
Public Shared Function GetCharImage(ByVal txt As String, ByVal fontFileName As String, ByVal fontSize As Single, ByVal imageFormat As Imaging.ImageFormat) As String

Dim filePath As String = String.Empty
' カレントフォルダをAssemblyと同じ場所に変更
Dim uriPath = System.Reflection.Assembly.GetExecutingAssembly.CodeBase
Dim uri = New System.Uri(uriPath)
System.Environment.CurrentDirectory = IO.Path.GetDirectoryName(uri.LocalPath)

Dim pfc As New System.Drawing.Text.PrivateFontCollection()
Dim fnt As Drawing.Font = Nothing
Dim img As Drawing.Bitmap = Nothing
Dim g As Drawing.Graphics = Nothing
Dim b As Drawing.SolidBrush = Nothing

Try

' フォントファイルのフルパス
Dim fontFilePath = IO.Path.GetFullPath(fontFileName)
' フォント追加
pfc.AddFontFile(fontFilePath)
fnt = New Drawing.Font(pfc.Families(0), fontSize)
' ダミーの画像を作成
img = New Drawing.Bitmap(5000, 5000)
g = Graphics.FromImage(img)
b = New Drawing.SolidBrush(Color.Black)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic

' 文字列のサイズを取得
Dim r = g.MeasureString(txt, fnt, img.Width)
If img IsNot Nothing Then
img.Dispose()
img = Nothing
End If
' 保存用画像の作成
img = New Drawing.Bitmap(CInt(r.Width), CInt(r.Height))
If g IsNot Nothing Then
g.Dispose()
g = Nothing
End If

g = Graphics.FromImage(img)

' 文字を描画
g.DrawString(txt, fnt, b, 0S, 0S)
filePath = String.Format("{0}.{1}", txt, imageFormat.ToString.ToLower)
' 画像を保存
img.Save(filePath, imageFormat) ' ←ここでエラーとなります

Catch ex As Exception

Throw

Finally

If b IsNot Nothing Then
b.Dispose()
b = Nothing
End If
If g IsNot Nothing Then
g.Dispose()
g = Nothing
End If
If img IsNot Nothing Then
img.Dispose()
img = Nothing
End If
If fnt IsNot Nothing Then
fnt.Dispose()
fnt = Nothing
End If
If pfc IsNot Nothing Then
pfc.Dispose()
pfc = Nothing
End If

End Try

Return filePath

End Function

<エラー>
System.Runtime.InteropServices.ExternalException: GDI+ で汎用エラーが発生しました。
場所 System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
場所 CharTest.CharCreator.GetCharImage(String txt, String fontFileName, Single fontSize, ImageFormat imageFormat)

引用返信 編集キー/
■82901 / inTopicNo.2)  Re[1]: 新規作成したBitmapのSaveメソッドでエラーが発生する
□投稿者/ 渋木宏明 (6回)-(2017/02/18(Sat) 10:19:11)
直接の回答ではありませんが。。

System.Drawing のヘルプ

https://msdn.microsoft.com/ja-jp/library/system.drawing(v=vs.110).aspx

の下の方に

>クラス内で、 System.Drawing 名前空間は、Windows または ASP.NET サービス内での使用はサポートされません。
>これらのアプリケーションの種類のいずれかの内側からこれらのクラスを使用しようと、予期しない問題が発生する可能性があります、
>低下しているなどのサービスのパフォーマンスと実行時の例外です。 サポートされている別の方法を参照してください。
>Windows Imaging Componentsします。

と書かれていますが、大丈夫でしょうか?

引用返信 編集キー/
■82925 / inTopicNo.3)  Re[2]: 新規作成したBitmapのSaveメソッドでエラーが発生する
□投稿者/ はるた (2回)-(2017/02/20(Mon) 09:13:41)
ご指摘ありがとうございます。

> System.Drawing のヘルプ
>
> https://msdn.microsoft.com/ja-jp/library/system.drawing(v=vs.110).aspx
>
> の下の方に
>
> >クラス内で、 System.Drawing 名前空間は、Windows または ASP.NET サービス内での使用はサポートされません。
> >これらのアプリケーションの種類のいずれかの内側からこれらのクラスを使用しようと、予期しない問題が発生する可能性があります、
> >低下しているなどのサービスのパフォーマンスと実行時の例外です。 サポートされている別の方法を参照してください。
> >Windows Imaging Componentsします。
>
> と書かれていますが、大丈夫でしょうか?

これはSystem.Drawing関連のものがWindows上では使用できないと言う事なんでしょうか?
そうだとすると実行時の例外とも書かれているので使用は難しそうです。

> >Windows Imaging Componentsします。

とあるのでこれについて調べてみます。



引用返信 編集キー/
■82926 / inTopicNo.4)  Re[3]: 新規作成したBitmapのSaveメソッドでエラーが発生する
□投稿者/ 魔界の仮面弁士 (1134回)-(2017/02/20(Mon) 09:56:46)
No82925 (はるた さん) に返信
> これはSystem.Drawing関連のものがWindows上では使用できないと言う事なんでしょうか?

.NET .4 まではこの記述は無かったのですが、4.5 から追加されています。

意味としては、System.Windows.Forms の UI スレッドからなら OK ですが、
service での利用は避けるように、ということだと思います。


4.5 から仕様が変わったということではなく、そもそも System.Drawing の
ベース技術である「GDI+」がシングルスレッドで動いているために、
GC 時にデッドロックを発生されることがあったという理由のようです。

まぁ、シングルスレッドとデッドロックというのは、私も人から聞いただけで
実際に動作検証したわけではありません。情報ソースは asprangers.com らしいのですが、
残念ながらドメインごと無くなっているようです。

サイト名を頼りにインターネットアーカイブで掘り返してみたら、
2012/03/23 当時の記事に、こんな記述を見つけました。

[Why you should not use System.Drawing from ASP.NET applications] By Jask200223, at March 2012 07:22
http://web.archive.org/web/20160418085644/http://asprangers.com/post/2012/03/23/Why-you-should-not-use-SystemDrawing-from-ASPNET-applications.aspx


> Windows Imaging Components
描画系のライブラリとしてこんなものもあるようです。
https://blogs.msdn.microsoft.com/dotnet/2017/01/19/net-core-image-processing/
引用返信 編集キー/
■82932 / inTopicNo.5)  Re[4]: 新規作成したBitmapのSaveメソッドでエラーが発生する
□投稿者/ はるた (3回)-(2017/02/20(Mon) 11:45:24)
情報提供ありがとうございます。

>>これはSystem.Drawing関連のものがWindows上では使用できないと言う事なんでしょうか?
>
> .NET .4 まではこの記述は無かったのですが、4.5 から追加されています。
>
> 意味としては、System.Windows.Forms の UI スレッドからなら OK ですが、
> service での利用は避けるように、ということだと思います。

そう言う事ですか。
今回の要件では使用できそうにないですね。

> サイト名を頼りにインターネットアーカイブで掘り返してみたら、
> 2012/03/23 当時の記事に、こんな記述を見つけました。
>
> [Why you should not use System.Drawing from ASP.NET applications] By Jask200223, at March 2012 07:22
> http://web.archive.org/web/20160418085644/http://asprangers.com/post/2012/03/23/Why-you-should-not-use-SystemDrawing-from-ASPNET-applications.aspx

英語はあまり得意ではないので理解が間違ているかもしれませんが、リサイクルが必要である点は共通しています。
状況的にはデッドロックが発生しているのかもしれません。
速やかにDisposeすれば回避できるような事も書いてあるようですが、サービス利用は避けるようにとの事なのであきらめた方が良さそうですね。

>>Windows Imaging Components
> 描画系のライブラリとしてこんなものもあるようです。
> https://blogs.msdn.microsoft.com/dotnet/2017/01/19/net-core-image-processing/

紹介頂いた中には過去に検証したようなライブラリもあり、Windows Imaging Componentsよりは敷居が低そうです。
検証しながら利用を検討したいと思います。



引用返信 編集キー/
■82951 / inTopicNo.6)  Re[5]: 新規作成したBitmapのSaveメソッドでエラーが発生する
□投稿者/ はるた (4回)-(2017/02/21(Tue) 09:17:03)
System.Drawingは使用せず、他のライブラリを使用する事で対応するため解決とします。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ