DOBON.NET DOBON.NETプログラミング掲示板過去ログ

pictureboxでの画像表示について

環境/言語:[vb.net 2008]
分類:[.NET]

こんにちは。
vb.netを始めて3ヶ月の初心者です。

質問なのですが、このサイトで見つけた
http://dobon.net/vb/dotnet/graphics/zoominout.html
↑ピクチャボックスの画像をクリックして拡大、縮小表示できるようにする
を使い、tifファイルを表示し、拡大縮小を行えるようなプログラムを作成しています。

動きとしては、CheckedListBoxで表示したいファイルを選択し、
その選択したファイルをpictureboxに表示する、というものです。

そこで、サイズの大きなファイル(9360*20332 361KB)を選択し、
表示しようとすると
'画像を指定された範囲に描画する
e.Graphics.DrawImage(img, imgRect)
↑の時点で「OutOfMemoryException」エラーが出てしまいます。
タスクマネージャで見た所、
メモリの使用量がそんなにあがっているわけではなさそうなんです。

ちなみに、容量が大きなファイル(3072*2304 20MB)は問題なく表示が出来ます。

そして更に大きなファイル(13248*39370 1.4MB)については
'表示する画像を読み込む
img = New Bitmap(TextBox1.Text)
↑の時点で「ArgumentException」エラーが出て
使用されたパラメータが有効ではありません。
と出てしまい、途方に暮れています。

ここの過去ログやインターネットで色々調べてはみたのですが、
解決策が見つからず、本当に困っています。
全く手も足も出ない状態なので、アドバイス頂けたら助かります。。
宜しく御願いします。
■No24666に返信(vb初心者さんの記事)
> そこで、サイズの大きなファイル(9360*20332 361KB)を選択し、
>「OutOfMemoryException」エラー
(snip)
> そして更に大きなファイル(13248*39370 1.4MB)については
> 「ArgumentException」エラー
(snip)
> ちなみに、容量が大きなファイル(3072*2304 20MB)は問題なく表示が出来ます。

ここでいう「サイズ」が、ファイルサイズなのか画像サイズなのか曖昧ですが:

ファイルサイズ小、画像サイズ中(361KB、 9,360x20,332)は OutOfMemoryException で、
ファイルサイズ中、画像サイズ大(1.4MB、13,248x39,370)は ArgumentException 、
ファイルサイズ大、画像サイズ小( 20MB、 3,072x 2,304)は OK 、

という状況なのですね。


> 解決策が見つからず、本当に困っています。
あまり大きい画像だと、GDI+ ではエラーになるかも知れませんね。
ちなみに、それらの画像フォーマットは何ですか?
■No24667に返信(魔界の仮面弁士さんの記事)
アドバイスありがとうございます。

> ここでいう「サイズ」が、ファイルサイズなのか画像サイズなのか曖昧ですが:
>
> ファイルサイズ小、画像サイズ中(361KB、 9,360x20,332)は OutOfMemoryException で、
> ファイルサイズ中、画像サイズ大(1.4MB、13,248x39,370)は ArgumentException 、
> ファイルサイズ大、画像サイズ小( 20MB、 3,072x 2,304)は OK 、
>
> という状況なのですね。

サイズは画像サイズの事です。うまく説明が出来てなくてすみません。

>あまり大きい画像だと、GDI+ ではエラーになるかも知れませんね。

また質問になってしまうのですが、
GDI+ ではエラーになってしまうかもという事ですが
他の方法で表示する事は出来るのでしょうか?

>ちなみに、それらの画像フォーマットは何ですか?

画像フォーマットはTIFです。
あと、ファイル形式はTIFF G4-MMR圧縮です。という答えで良いんですかね?(汗

宜しく御願いします。
■No24668に返信(vb初心者さんの記事)
> 画像フォーマットはTIFです。
> 他の方法で表示する事は出来るのでしょうか?

すみません、具体的な解決方法は持ち合わせていません。

Bitmap クラスで展開できないとなると、TIFF 内の各ストリップを読み取って、
自前でゴリゴリ処理するぐらいしか思いつかず…。
http://www.snap-tck.com/room03/c02/cg/cg.html

あとは、TIFF 展開可能な外部ライブラリに、適当な物がないか探してみるとか。
http://www.freedownloadscenter.com/Best/free-large-tiff.html
http://f35.aaa.livedoor.jp/~mokeke/susiespi.html
■No24669に返信(魔界の仮面弁士さんの記事)
魔界の仮面弁士さん、ご回答ありがとうございます!
教えて頂いたサイトを見て自分なりにもう一度考えてみます。

もし、解決方法をお持ちの方がいらっしゃいましたら、ご教授ください。

宜しく御願いします。
2009/06/03(Wed) 23:38:33 編集(投稿者)

■No24666に返信(vb初心者さんの記事)
> そして更に大きなファイル(13248*39370 1.4MB)については
これって、1.4GBの間違いじゃないでしょうか?

32bitのWindowsでは1プロセスが使える(仮想)メモリの限界が2GBという上限にあります。
実際にはDLLが読み込まれたり、自分のコードが読み込まれたりして、2GB限界までは使えません。

例に挙げられたいる画像が24bitだと仮定すると、13248 * 39370 * 3 = 1,564,721,280バイトものメモリが必要ですが、恐らく確保に失敗します。
GDI+以外のライブラリを使ってもこの壁は越えられません。


実現する可能性があるとすれば、表示する部分だけをメモリに読み込み、それを描画できるような仕組みが必要です。

なお、こういった巨大な画像を部分的に読み込む手法には特許があるかもしれないという噂を聞いています。
真偽の程や請求項については確認していません。
2009/06/04(Thu) 05:01:46 編集(投稿者)

少し調べてみましたが、@ITの掲示板に似たような質問がありました。

VB PoitureBoxで表示時にOutOfMemoryException − Insider.NET − @IT
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34895&forum=7

解決はしていないようですが、参考になるかもしれません。
■No24671に返信(Azuleanさんの記事)
アドバイスありがとうございます。

> そして更に大きなファイル(13248*39370 1.4MB)については
> これって、1.4GBの間違いじゃないでしょうか?
このファイルは確かに1.4MBです。1,486KBとなっていますので・・・。

>実現する可能性があるとすれば、表示する部分だけをメモリに読み込み、それを描画できるような仕組みが必要です。
やはり簡単に行える事ではなさそうですね…。

ありがとうございました。
別の方法がないか、少し検討してみます。
■No24672に返信(管理人さんの記事)
>少し調べてみましたが、@ITの掲示板に似たような質問がありました。

>VB PoitureBoxで表示時にOutOfMemoryException − Insider.NET − @IT
>http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34895&forum=7

>解決はしていないようですが、参考になるかもしれません。
ありがとうございます。このサイトは私も確認しました。
しかし、私的に有益な情報は得られず…という感じですかね。

何か別の方法がないか、検討してみます。

大きな画像サイズのファイルを表示する、という事に対して
もし何かいい方法をお持ちの方がいらっしゃいましたら、
ご指摘宜しく御願い致します。
■No24674に返信(vb初心者さんの記事)
> 大きな画像サイズのファイルを表示する、という事に対して
> もし何かいい方法をお持ちの方がいらっしゃいましたら、
>

TIFFのフォーマットを解析して、表示範囲でデータを読み取る。
でも、これは難しいと思われる。

TIFFのフォーマットに関する日本語ドキュメントを知りませんか。
http://forums.adobe.com/thread/414171

簡単なのは、大きいTIF画像をツールで表示可能な範囲まで刻んで
幾つかのファイルに分けておく。
表示する場合は、分割したファイルをそれぞれのPictureBoxで表示
■No24673に返信(vb初心者さんの記事)
>>これって、1.4GBの間違いじゃないでしょうか?
> このファイルは確かに1.4MBです。1,486KBとなっていますので・・・。

圧縮フォーマットであることを見落としていました。すみません。


GDI+が画像として扱う際には展開するので1.4GBくらいになります。
DrawImageの際には作業領域としてさらに消費するはずなので、単純なやり方じゃ無理です。


要件次第でいくつかのアプローチはあるかもしれません。
ただ、元の画像ファイルを何かのプロパティに設定すればOKという方法はありません。
2009/06/05(Fri) 04:01:57 編集(投稿者)

画像をファイル名で読み込むとき、そのファイルが存在しなかったり、画像ファイルではなかった場合などにArgumentExceptionがスローされます。

同じく画像をファイル名で読み込むとき、その画像形式が有効でなかったり、GDI+でサポートしていないピクセル形式だった場合などにOutOfMemoryExceptionがスローされます。ただこの場合例外がスローされるのは読み込み時であって、表示時ではありません。よって今回のケースはこれに当たらないかもしれません。

詳しくは、MSDNのImage.FromFileメソッドの説明をご覧ください。

http://msdn.microsoft.com/ja-jp/library/system.drawing.image.fromfile.aspx

> >VB PoitureBoxで表示時にOutOfMemoryException − Insider.NET − @IT
> >http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34895&forum=7
>
> ありがとうございます。このサイトは私も確認しました。
> しかし、私的に有益な情報は得られず…という感じですかね。

ということは、CLRProfilerも試されたのでしょうか?もしそうであれば、結果を教えてください。

DOBON.NET | プログラミング道 | プログラミング掲示板