- - PR -
VB PoitureBoxで表示時にOutOfMemoryException
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-11-17 11:11
ちょうど今、画像処理系のPGやってますもので、後学も兼ねて手元で大雑把にコーディングしてみました。
Dim original As New System.Drawing.Bitmap(OpenFileDialog.FileName) Dim aspect As Decimal = (original.HorizontalResolution * original.Height) / (original.VerticalResolution * original.Width) Dim thumnail As System.Drawing.Bitmap = original.GetThumbnailImage(Me.PictureBox.Width, Me.PictureBox.Width * aspect, Nothing, System.IntPtr.Zero) Me.PictureBox.Image = thumnail ※GetThumbnailImage は 800×600 規模のサイズには不向きらしいですが1行で縮小できるのは便利でして(笑) thumnail と original の縮尺比を考慮しつつ、UI(thumnail)上でのトリミング結果を original に適用して保存、と。 | ||||||||
|
投稿日時: 2006-11-17 11:46
こば様、コメントありがとうございました。
最初のサンプルコードでは、ファイル入力については下記のスレッドを 参考に、FileStreamで入力しております。 件名:ImageクラスのFileStreamで読み込んだ画像の保存 こば様のコードをそのまま流用させていただいた場合、入力できていたファイルD (140MBくらい)もGetThumbnailImage部分でOutOfMemoryExceptionとなって しまいました そこで以下のようにしますと、ファイルDは○ですが、やはりファイルAは thumnailのコンストラクタでOutOfMemoryExceptionとなってしまいました。 やっぱり200MB超はだめなんでしょうか… ●サンプルコード2 Dim original As Bitmap Private Sub LoadFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadFile.Click Dim OpenFileDialog1 As New OpenFileDialog() OpenFileDialog1.Filter = "TIFF ファイル|*.tif" If OpenFileDialog1.ShowDialog() = DialogResult.OK Then Dim hStream As New System.IO.FileStream(OpenFileDialog1.FileName, System.IO.FileMode.Open) original = System.Drawing.Bitmap.FromStream(hStream) hStream.Close() Dim aspect As Decimal = (original.HorizontalResolution * original.Height) / (original.VerticalResolution * original.Width) Dim thumnail As Bitmap = New Bitmap(original, Me.PictureBox1.Width, Me.PictureBox1.Width * aspect) Me.PictureBox1.Image = thumnail thumnail.Dispose() End If OpenFileDialog1.Dispose() End Sub | ||||||||
|
投稿日時: 2006-11-17 16:23
重ねて記載いたしますが、サンプルファイルが以下のURLにございます。
もしお手間でなければサンプルとしてご使用いただければと存じます。 ファイルA(× 208MB)とファイルD(○ 137MB)に相当するものを 圧縮して同梱してあります。画像はまっしろです。 #ファイルサイズは400KB弱ですが、解凍すると合計350MBくらいに なります。ご注意ください。 http://www.dekaino.net/~mikage/largewhite.zip | ||||||||
|
投稿日時: 2006-11-17 16:33
根本的な問題に、甕星様にコメントいただきました
という部分があるかと思いました。 これを確認するために、現在のアプリケーション上での総空きメモリ空間や 連続空きメモリ空間を確認するような手法はあるのでしょうか? [ メッセージ編集済み 編集者: みかげ☆ 編集日時 2006-11-17 16:34 ] | ||||||||
|
投稿日時: 2006-11-20 13:32
何がどうメモリを使っているか調べるなら
CLRプロファイラ を試されてはいかがでしょう。 ところでなんらかの方法で200MBの読み込みが成功したとして今度は300MBでOufOfMemoryExceptionが発生した場合はどうするのでしょうか。なので何MBの画像を読み込んでも(解像度を変えたり、圧縮したりして)表示できるようにすることを考えた方が良いのではないでしょうか。 | ||||||||
|
投稿日時: 2006-11-20 14:20
ryuuji様、コメントありがとうございます。
CLRプロファイラをお教えいただき、ありがとうございます。 早速試してみます。 引用文が前後します。
こば様にお教えいただいたコードを元に、サンプルコード2で 画像サイズをかえてから表示しようとおもったのですが、 表示前の変換する部分でOufOfMemoryExceptionとなってしまいました。 Dim thumnail As Bitmap = New Bitmap(original, Me.PictureBox1.Width, Me.PictureBox1.Width * aspect) が発生場所です。 WWWを検索しても画像の拡大縮小はおおよそ似たり寄ったりな手法が多く、 他にどのような解像度を変えたり、圧縮したりする方法があるのかが わかっていません…
そういうわけでして方法が分からないので、とりあえず現状としては 「限界を知る」、という感じでしょうか。 どうも当初予定の500Mはとても無理そうなので、それならばとりあえず どこまでいけるのかを知りたいといったところです。 | ||||||||
|
投稿日時: 2006-11-21 13:16
理解しました。200MBを既定のライブラリ(Bitmap)で読み込む、ということにはこだわってはないのですね。
このコードの厳密な意味は知りませんが、リサイズなり解像度の変更なりがBitmapオブジェクトへの操作ならば、そもそもメモリが足りなくてBitmapオブジェクトを作れない事が例外の原因なので無理な気がします(鶏が先か、卵が先かみたいな?)。 Webを探してみると同じような問題を抱えている方が沢山いるようです。CompactFramework向けのオープンソースライブラリでOpenNETCF.orgというものがあるそうです。CF向けですがオープンソースなのでソースコードを参考にしてみてはどうでしょうか。 追記: OutOfMemoryExceptionが発生するか事前に調べる方法が.NET 2.0で追加された、と聞いた気がします。限界が何MBか調べるより、こっちでチェックした方がいいのでは(そんなメソッドがあるならですが・・・)。 [ メッセージ編集済み 編集者: ryuuji 編集日時 2006-11-21 13:19 ] |