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

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

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

Re[3]: ImageLockMode::WriteOnly


(過去ログ 44 を表示中)

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

■23501 / inTopicNo.1)  ImageLockMode::WriteOnly
  
□投稿者/ 雲 (7回)-(2008/08/17(Sun) 14:46:19)

分類:[C++/CLI] 

C++/CLI に限らないかもしれませんが、Bitmap の生データを扱う必要があったので、
以下のようなコードを書いてみました。

すると。。。Bitmap の領域をロックする際に、ImageLockMode::WriteOnly(書き込みしかしないので)
と指定してみたところ、なんと、ロックしただけで、ロックした Bitmap のデータを黒一色に変換
されてしまいました。

ちなみに、ImageLockMode::ReadWrite と指定するとそんなことはおこりません。。。
MS のサイトを見てみましたが、ImageLockMode::WriteOnly を指定した際に黒一色(R=G=B=0) にBitmap を
初期化するという記述は見つけられませんでした。

ちょっと、びっくりしましたが、何か、これには、深いわけとかあるのでしょうか?
僕のへなちょこな知識と経験では、さっぱり、わかりません(^^)。

------------------------------------------------------------
C++/CLI でのImageLockMode::WriteOnly の動作に関するサンプルコード
(当然、C# に移植可能です)
------------------------------------------------------------
using namespace System::Drawing::Imaging;
using namespace System::Drawing;

int main()
{
Bitmap ^bmp = gcnew Bitmap( 100, 100 );

Graphics::FromImage( bmp )->Clear( Color::Blue );

// 最初に、Bitmap を出力しておく(青一色)
bmp->Save( "before.bmp" );

// Bitmap 領域をロックしてみる(ここで、ImageLockMode::WriteOnly から、ImageLockMode::ReadWrite に変えると出力されるbmpが変わる)
BitmapData ^bmpData = bmp->LockBits( Rectangle(0, 0, bmp->Width, bmp->Height), ImageLockMode::WriteOnly, PixelFormat::Format24bppRgb );

// 何も処理をせずに

// Bitmap の領域のロックを解放
bmp->UnlockBits( bmpData );

// 再度、Bitmap を出力(ここでは、何故か、黒一色)
bmp->Save( "after.bmp" );
}
引用返信 編集キー/
■23506 / inTopicNo.2)  Re[1]: ImageLockMode::WriteOnly
□投稿者/ NyaRuRu (56回)-(2008/08/17(Sun) 16:36:15)
No23501 (雲 さん) に返信
> ちょっと、びっくりしましたが、何か、これには、深いわけとかあるのでしょうか?
> 僕のへなちょこな知識と経験では、さっぱり、わかりません(^^)。

その方が高速だからだと思います.
引用返信 編集キー/
■23507 / inTopicNo.3)  Re[2]: ImageLockMode::WriteOnly
□投稿者/ NyaRuRu (57回)-(2008/08/17(Sun) 16:44:54)
2008/08/17(Sun) 16:47:13 編集(投稿者)
2008/08/17(Sun) 16:45:57 編集(投稿者)

No23506 (NyaRuRu さん) に返信
> ■No23501 (雲 さん) に返信
>>ちょっと、びっくりしましたが、何か、これには、深いわけとかあるのでしょうか?
>>僕のへなちょこな知識と経験では、さっぱり、わかりません(^^)。
>
> その方が高速だからだと思います.

(追記)
黒色にするから高速という意味ではなくて,初期値 0 (0x00000000) が黒を現すため,結果的に黒く塗りつぶす副作用があるように見えるという話だと思います.

LockBits/UnlockBits で必要な処理を考えてみると分かりやすいかと.

LockBits:
(1) データの入出力に使うためのバッファサイズを計算し,バッファを確保する
  ImageLockMode::UserInputBuffer は,この作業が不要であることを示す最適化ヒントになる
(2) 対象となるビットマップから該当領域のデータをバッファにコピーする
  ImageLockMode::WriteOnly は,この作業が不要であることを示す最適化ヒントになる

UnlockBits:
(1) LockBits で確保したバッファからビットマップの該当領域へコピーする
  ImageLockMode::ReadOnly は,この作業が不要であることを示す最適化ヒントになる
(2) LockBits で確保したバッファを解放する.
  ImageLockMode::UserInputBuffer は,この作業が不要であることを示す最適化ヒントになる

引用返信 編集キー/
■23510 / inTopicNo.4)  Re[3]: ImageLockMode::WriteOnly
□投稿者/ 雲 (8回)-(2008/08/17(Sun) 20:48:16)
NyaRuRu さん。納得しました。

ImageLockMode::WriteOnly ではロックした全ての領域をユーザーが
データをデータをセットすることを要求しているのですね。

てっきり、WriteOnly で指定した時にも、現在の値がコピーされていると
ものと誤解していました。

でも、よく考えたら、そうですよね。WriteOnly と ReadWrite の2つのモードが
ある時点で、

ReadWrite ... bmp 領域から、データをコピーする
WriteOnly ... bmp 領域から、データをコピーしない

と言う仕様になっていることに気がつくべきでした。

まだまだ、力不足ですね。頑張ります。ありがとうございました。



引用返信 編集キー/


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -