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

BITMAP.Clone()について

環境/言語:[XP VB.NET]
分類:[.NET]

みなさん、こんばんは。
BITMAP.Clone() について教えてください。
現在VB.NET2003で、PictureBoxをベースにしたカスタムコントロール(以下Aと呼ぶ)を作成していて、ファイルから読み込んだBitmapの管理と、そのClone作成で悩んでいます。
やりたいことは、複数のAのコントロール間でRectangeを指定した画像のコピーを実現したいのです。ここで読み込んだファイルをロックせず、また極力シンプルな構造にしたいこともあります。以下試したことです。
(文字数の関係があるのでサンプルプロジェクトを添付しています)

【Test #1】(http://dobon.net/vb/dotnet/graphics/drawpicture2.html)
TipsにあるようにFileStreamからBitmapクラスを生成した。しかしStreamをCloseするとBitmap.Clone()でOutOfMemory例外が発生する。
StreamをCloseしないとファイルがロックされ削除できず。

Dim fs As FileStream = New System.IO.FileStream(FName, IO.FileMode.Open, IO.FileAccess.Read)
BM = New Bitmap(fs)
' fs.Close() ←これをやると Clone時に例外発生、コメントのままだとファイルを削除できず
PictureBox1.Image = BM
Dim CloneBM As Bitmap = BM.Clone(rc, BM.PixelFormat)


【Test #2】
読み込んだStreamからByte配列へ格納し、MemoryStreamに格納しBitmapを生成した。これでは無駄(時間)が多すぎ。(サンプル参照ください)

【Test #3】
Bitmapをファイルから生成しこれをCloneした。でもファイルは削除できず

Dim TMPBM As Bitmap = New Bitmap(FName)
BM = TMPBM.Clone()
TMPBM.Dispose()
PictureBox1.Image = BM
Dim CloneBM As Bitmap = BM.Clone(rc, BM.PixelFormat)

どうしたら解決できるでしょうか?
あと腐れなくメモリ上のBitmapをコピーできる方法を探しています。
(この記事にはファイル"CloneTest.lzh"が添付されていましたが、削除されました。)
私の環境で試したところ
問題なく動作を確認しました

--MSDN Bitmap.Cloneメソッドより引用--
解説
rect パラメータで指定した四角形がソース ビットマップの範囲外にある場合、このメソッドは OutOfMemoryException をスローすることがあります。
--ここまで--

多分こっちが原因なのでは?
bellさん、確認していただきありがとうございます。
また説明不足ですみませんでした。

TipsのようにFileStreamからBitmapを生成した場合、そのBitmapをCloneするとOutOfMemoryとなり、直接画像ファイルから生成したときは問題ありませんでした。ですのでrectパラメータは問題ないようです。

なおOutOfMemoryが発生するのはFileStreamをCloseするからであり、CloseしなければOutOfMemoryは発生しませんでした。ただしFileStreamをCloseしないと読み込んだ画像ファイルがロックされ続けるため、Cloneメソッドを使用する場合はTipsの対策の効果がないようです。

結局Bitmapクラスはコンストラクタの引数のオブジェクトをロックするという仕様としてあきらめるしかないのでしょうか?
あきらめてください。

たとえばマルチページTIFFのようなものでもページ単位でファイルから読み直しを行います。
このようなこともありファイルをロックしていると思われます。
そういうものですか。
一度ファイルからメモリ上(Byte配列)に展開し、それをBitmpaクラスに指定しようと思います。イメージサイズが大きいときにスピードが少し気になりますが、あきらめます。
みなさん、お返事ありがとうございました。
解決済み!
  • 題名: Re[5]: BITMAP.Clone()について
  • 著者: 中 博俊
  • 日時: 2005/01/16 14:33:57
  • ID: 8447
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
New Bitmap(bmp)
で、新しいBitmapにコピーされますよ。

ただし全てがコピーされるわけじゃなくってDPIが保持されないとか、現在のページだけ(マルチページな画像の場合)とかやや違いはありますが。

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