直接メモリ上にピクセルデータを打つには?

解決


匿名希望  2005-06-03 05:51:34  No: 57682

Bitmapのピクセルデータを直接メモリDC上に描き込みたいのですが
それらしいやり方がわかりません。

DirectXのように直接サーフェイスをLockしてピクセルデータを叩き込むようなことはできないのでしょうか?
.NETではLockBitsなるものがあるみたいなのですが
あいにく私が使用しているのはVC6です。

SetPixelを使ってみますがやはり速度的に問題があります。

空のDIBを一つ作成し、そこにピクセルデータを直接描いてから
メモリDC→画面描画とすれば。。。
と、思ったのですが直接メモリDCに描けるほうが手間が省けると思いました。

VC6でもっと効率よくピクセルデータをメモリ上に描き込める方法はないでしょうか?


望みかわからないけど  2005-06-03 05:55:43  No: 57683

DIBSection とか?


匿名希望  2005-06-03 06:32:46  No: 57684

メモリDC自体に直接ピクセルデータを描きたいので
DIBSectionを使うとなるとやっぱりオフスクリーンのような
DIBを一つ作ってそれ経由でメモリDCに描き込みになってしまうかと思います。

せっかく考えて頂いたのに申し訳ないです。


シャノン  2005-06-03 06:48:01  No: 57685

> メモリDC自体に直接ピクセルデータを描きたいので
> DIBSectionを使うとなるとやっぱりオフスクリーンのような
> DIBを一つ作ってそれ経由でメモリDCに描き込みになってしまうかと思います。

何がしたいのかよくわかりません。
ピクセルデータの集まりが DIB です。
DIB セクションにデータを書き込むことがすなわち、メモリに直接ピクセルを打つことではないのでしょうか。

メモリDC ではなく、ビデオメモリに直接ピクセルを打ちたいのでしたら、DirectX を使うか、さもなくばビデオドライバを作らなければ無理ではないでしょうか。


匿名希望  2005-06-03 07:07:22  No: 57686

> 何がしたいのかよくわかりません。
SetPixelの高速版のようなものがあるのかな?と、いうことです。

> ピクセルデータの集まりが DIB です。
なのでSetPixelの高速版のようなものがないのであれば、
Work用のDIBを一つ用意し、そこに描き込みたいピクセルデータを打ち込んでから
BitBltなりでメモリDCにコピーしてから描画しようということです。

やはりDirectXなどを使わないとむりなんですかね?


Ryo  2005-06-03 07:37:56  No: 57687

とりあえずSetPixelよりは、SetPixelV  のほうがちょっとだけ早い。
でも、別のところに描画してから転送するほうがはるかに早い

やりたいことはこんな感じかな?
***************
CDCからGetCurrentBitmapで、CBitmapを取得し
そこからGetBitmapでBITMAP構造体(.bmBits)を取得して、直接書く
***************
これでできそうだけど、
直接メモリを打つとなると、現在のカラーモードだけではなく
ビデオボードによってRGBの扱い方が変わったりするので汎用性が大変ですよ。
#ためしたことないので想像なんですが、描画が早いと同期の問題もでてきそう。


匿名希望  2005-06-03 07:50:55  No: 57688

回答ありがとうございます。

ちょっと今日は時間ないのでまた明日試してみて結果を報告させてもらいたいと思います^^;

やはり色々問題がでてくるんですね。。。

DIBに描画してから転送が無難なのか・・・。


匿名希望  2005-06-03 17:54:20  No: 57689

Ryoさんに回答頂いた後、自分で調べた結果を報告します。
自分の調べが間違っていたらごめんなさい。

CDC::GetCurrentBitmap
現在選択されている CBitmap オブジェクトへのポインタを返します。
(MSDN参照)

すいません、説明抜けてました。。。
MFC使っていないのです;;
申し訳ないです。

GetBitmap
Bitmapを読み込む。
(他サイト様参照)

画像データ自体は既に読み込んであります。
後はそれをBitBltとかStrechBltでメモリDCに矩形転送するのではなく、
ドットで打ち込みたいです。

Ryoさんの伝えたいことと私の認識に違いがあればご指摘下さい。


Ban  2005-06-03 19:45:57  No: 57690

そういう高速/低水準なアクセスを提供するのが DirectX の機能ですから、
汎用性重視、機能重視の API 群で速度を上げるのは多分不可能では?
素直に DirectX を使うか、DibSection でブロック転送するのがいいと思います。


シャノン  2005-06-03 19:58:42  No: 57691

> SetPixelの高速版のようなものがあるのかな?と、いうことです。
ありません。なので、

> 後はそれをBitBltとかStrechBltでメモリDCに矩形転送するのではなく、
ドットで打ち込みたいです。
こういうことをする関数を作らなければならないでしょう。
CreateDIBSection と SetDIBitsToDevice の組み合わせが近いか?

> やはりDirectXなどを使わないとむりなんですかね?
「ビデオメモリに直に打ちたいならば」使わないと無理でしょう。


匿名希望  2005-06-03 20:48:33  No: 57692

皆さん回答ありがとうございます。

シャノンさんのおっしゃる通り
CreateDIBSection と SetDIBitsToDevice の組み合わせ
も、やはり考えてました。。。

今回はDirectXを使わずにやりたいので
"DibSection でブロック転送"
で、いきたいと思います。

毎回ありがとうございます。
助かります。


匿名希望  2005-06-03 20:49:12  No: 57693

すいません。
解決になります。チェック忘れてました^^;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加