<< Prev Page Next Page >>

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


.NETでパラパラマンガ

最近、サーモグラフィカメラを使ったプログラムをC#3.0で作っている(ラムダとか使っちゃってちょっと賢くなった気分)。

それで、カメラのAPIは1フレーム分の静止画像、というか、各ピクセルの赤外線シグナル値を返すようになっていて、静止画像を受け取るたびにBitmapオブジェクトに書き込んでGraphics.DrawImage()ってやってパラパラマンガみたいにしてカメラのリアルタイム映像を表示する必要があった。

そんでさくっとこんな

for (int y = 0; y < bmp.Height; x++) {
for (int x = 0; x < bmp.Width; x++) {
int idx = y * bmp.Height + x;
bmp.SetPixcel(x, y, SignalToColor(signal[idx]));
}
}
graphics.DrawImage(bmp);
感じで書いてみたところ、遅い遅い。秒間9フレームで画像を受け取ってるはずなのにカクカク動く。おっかしいなあ。

カメラのAPIを疑いつつも、もしやと思って調べてみたら、BitmapのSetPixel、GetPixelはすごく遅いらしい。そうだったのか!
LockBits() によって内部メモリをロックする。
 :
(略)
 :
これは、図を見ると前回の GetPixel() SetPixel() より100倍以上速い。
MemoNyanDum : Bitmap の内部色データにアクセスする (1)
ふぅん、と思って、上記の記事をまねて、unsafeでポインタなプログラム(わーい久しぶりにポインタだっ)でBitmapDataの内部配列に値を入れていくやり方に変えてみた。
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe {
byte* p = (byte*)data.Scan0;
for (int i = 0; i < signal.Length; i++) {
Color c = SignalToColor(signal[i]);
p[0] = c.R;
p[1] = c.G;
p[2] = c.B;
p += 3;
}
}
bmp.UnlockBits(data);
graphics.DrawImage(bmp);
そしたら、ものすごい速くなってチャキチャキ動画再生されるようになった。すごい。

ていうか、BitmapのSetPixelがそんなに遅い理由がわからない。配列に値をセットするだけじゃないのか。


この記事に対するコメント

この記事に対するコメントの投稿



管理者にだけ表示を許可する

この記事に対するトラックバック

トラックバックURL
http://tockri.blog78.fc2.com/tb.php/190-2ba3b980
この記事にトラックバックする(FC2ブログユーザー)

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。