- PR -

PictureBoxのロード方法について

1
投稿者投稿内容
とら
ベテラン
会議室デビュー日: 2006/10/04
投稿数: 54
投稿日時: 2007-01-05 15:47
PictureBoxに元のBMPファイルをロックせずに表示し、かつこれを
バイト配列として取り込みたいのですが、上手くいきません。

最初にやっていた方法は以下のとおりです。

// イメージ読み込み
pictureBox1.Image = Image.FromFile(@"C:\\MyDocuments\\My Pictures\\無題.bmp");

//バイト配列に変換
MemoryStream InMem = new MemoryStream();
pictureBox1.Image.Save(InMem, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] InByte1;
InByte1 = new byte[InMem.Length];
InMem.Position = 0;
InMem.Read(InByte1, 0, (int)InMem.Length);

上記の形式で、満足行く結果が得られていたのですが、この場合、元の
Bitmapファイルにロックが掛かってしまうことがわかりました。

http://support.microsoft.com/kb/311754/
MSのサポートサイトで上記の情報を得たので、イメージ読み込み部分を
以下のように変更しました。

// イメージ読み込み
FileStream fs;
fs = new FileStream(@"C:\\MyDocuments\\My Pictures\\無題.bmp",
FileMode.Open, FileAccess.Read);
pictureBox1.Image = System.Drawing.Image.FromStream(fs);
fs.Close();


この結果、元ファイルに対するロックはなくなりましたが、今度は
バイト配列に変換する部分
imgImage1.Image.Save(InMem, System.Drawing.Imaging.ImageFormat.Bmp);
で、「GDI+ で汎用エラーが発生しました。」の例外が出るように
なってしまいました。

Imageデータの取り扱い方法に何か問題があるのかもしれませんが、
回避方法をご存知の方はいらっしゃいませんか?

環境は
XP Pro SP2
VS2005
C#
です。

よろしくお願いします。
rvmx
大ベテラン
会議室デビュー日: 2002/09/26
投稿数: 184
お住まい・勤務地: 愛媛県
投稿日時: 2007-01-05 16:25
今日は

// イメージ読み込み
pictureBox1.Image = new Bitmap(Image.FromFile(@"C:\\MyDocuments\\My Pictures\\無題.bmp"));
とするとどうですか?。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2007-01-05 16:54
引用:

rvmxさんの書き込み (2007-01-05 16:25) より:
pictureBox1.Image = new Bitmap(Image.FromFile(@"C:\MyDocuments\My Pictures\無題.bmp"));


これだと FromFile で作成した Image インスタンスのロックしているファイルが解放されるのが遅れるので良くないですね。
new Bitmap したらすぐ Image インスタンスを Dispose しないと。



ところで、直接 MemoryStream にファイルを書き込むのはダメですか?
その MemoryStream からなら当然ロックとは無関係に Image を扱えますが。
とら
ベテラン
会議室デビュー日: 2006/10/04
投稿数: 54
投稿日時: 2007-01-07 13:48
rvmxさん、Hongliangさん、情報ありがとうございました。

今回は、Hongliangさんのご指摘のように、new Bitmap したらすぐImageインスタンスをDisposeする方法を取ることによって、期待した結果を得ることができました。

具体的には、以下のようなコードを記述しました。

Image im = Image.FromFile(@"C:\\MyDocuments\\My Pictures\\無題.bmp");
Bitmap bm = new Bitmap(im);
pictureBox1.Image = bm;
im.Dispose();

この結果、ファイルにロックも掛からずに、バイト配列への変換も問題なくできました。
コードがきれいか汚いかに関する自身はありませんが・・・

どうもありがとうございました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-01-07 14:46
pictureBox1.Image = Bitmap.FromFile(FileName);
_________________
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-01-07 15:57
引用:

Jittaさんの書き込み (2007-01-07 14:46) より:

pictureBox1.Image = Bitmap.FromFile(FileName);


この流れで、どうしてこのコード?
これはダメでしょう。

System.Drawing.Bitmap.FromFile メソッドもとい
System.Drawing.Image.FromFile メソッドでは、ファイルがロックされます。

Hongliang さんが仰るように Stream から Load しないと。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-01-07 16:18
この問題って、.NET 2.0 で直ってなかったんですね ;-p
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-01-07 16:33
引用:

じゃんぬねっとさんの書き込み (2007-01-07 15:57) より:
引用:

Jittaさんの書き込み (2007-01-07 14:46) より:

pictureBox1.Image = Bitmap.FromFile(FileName);


この流れで、どうしてこのコード?
これはダメでしょう。

System.Drawing.Bitmap.FromFile メソッドもとい
System.Drawing.Image.FromFile メソッドでは、ファイルがロックされます。

Hongliang さんが仰るように Stream から Load しないと。




あ、いや、元の質問、全然読んでいませんでしたm(__;)m

問題ではなく、仕様ですね。
引用:

Image.FromFile メソッド (String, Boolean)<microsoft.com> より:
このファイルは Image が破棄されるまでロックされます。


_________________
1

スキルアップ/キャリアアップ(JOB@IT)