表示しているクライアント領域の画像データを・・・ – プログラミング – Home

表示しているクライアント領域の画像デー...
 
通知
すべてクリア

[解決済] 表示しているクライアント領域の画像データを・・・

固定ページ 1 / 2

ガラ
 ガラ
(@ガラ)
ゲスト
結合: 20年前
投稿: 201
Topic starter  

VC++ 6.0 XP
表示しているクライアント領域の画像データをとりこみたいのですが、
CDC::GetPixel()では、おそいのですが、
なにか、いい手は、ないでしょうか?

CClientDC wDC(this);
CRect wRect;
GetClientRect(&wRect);// クライアント領域の大きさを得る

vector <COLORREF> wBuffer ;
int x,y ;
for(y = wRect.top;y < wRect.bottom;y++) {
for(x = wRect.left;x < wRect.right;x++) {
COLORREF wColor = wDC.GetPixel(x,y) ;
wBuffer.append(1,wColor) ;
}
}
なぜかGetPixel(1,0)のとき-1が返ってきます。


引用未解決
トピックタグ
ガラ
 ガラ
(@ガラ)
ゲスト
結合: 20年前
投稿: 201
Topic starter  

わかりません。SetPixelでかけるのに、GetPixelで読めないです。
CRect wRect;
GetClientRect(&wRect);// クライアント領域の大きさを得る
std::vector <COLORREF> wBuffer ;
int x,y ;
for(y = wRect.top;y < wRect.bottom;y++) {
for(x = wRect.left;x < wRect.right;x++) {
pDC->SetPixel(x,y,RGB(0xff,0,0)) ;
COLORREF wColor = pDC->GetPixel(x,y) ;
wBuffer.push_back(wColor) ;
}
}


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

とりあえず、BitBlt()転送してからの方が早いかも。

以下、C++Builderのサンプルですが、
VC++が分かる人ならきっと読めると思います。
http://www.ne.jp/asahi/protech/hiroaki/programing/cb.html#Q8

転送できたら、CBitmap::GetBitmapBits() でバッファに取り込めます。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> わかりません。SetPixelでかけるのに、GetPixelで読めないです。

新しいSDIプロジェクトで↓を試すとどうなります?

void CMy0409View::OnLButtonDown(UINT nFlags, CPoint point)
{
CClientDC dc(this);
dc.SetPixel(point.x, point.y, RGB(0, 0, 0xff));
int ret = dc.GetPixel(point.x, point.y);
TRACE((%d, %d) color = %06x\n, point.x, point.y, ret);

CView::OnLButtonDown(nFlags, point);
}


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

MDSNを読んで見ましょう。
> すべてのデバイスが GetPixel 関数をサポートするわけではありません。
> 詳細については、GetDeviceCaps メンバ関数の RC_BITBLT ラスタ機能に
> 関する解説を参照してください。

> RC_BITBLT Capable of transferring bitmaps.
対象がビットマップになっている必要があるみたいですね。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

追記、
ん、SetPixelも一緒だね。
対象はビットマップですね。
SetPixelはうまくいっているのですよね。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

GetPixelとSetPixelの組合せでやるとかなり遅いと思います。
一ピクセルずつ処理しないといけない訳でもあれば話は別ですけれど。
一般的に画像を取り込みたいときは、bunさんの方法を使うと思います。

提示されているソースでは画素毎に変換等をやっているわけではなくて
単純に写しているだけのようなのでそれならば、BitBltでやった方が
効率が良いと思います。

GetPixelがうまく行かないわけについてはちゃんと理解した方が良いと
思うのでそれはそれで追求した方が良いとは思いますけれど。


返信引用
ガラ
 ガラ
(@ガラ)
ゲスト
結合: 20年前
投稿: 201
Topic starter  

bunさん、たいちうさん、ITOさん、PATIOさん、レスありがとうございます。
どうやら、ビットマップになっていないとだめなようですね。
ソースは、すこし時間が今すこし、UPは、お時間をくださいね。
もう、八方ふさがりになっていたので、すごく助かりました。
まだ、動作するかどうかわかりませんが、きっといい結果につながると思います。


返信引用
ガラ
 ガラ
(@ガラ)
ゲスト
結合: 20年前
投稿: 201
Topic starter  

void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// CClientDC wDC(this);

CDC wDC ; // デバイスコンテキストを実体化
// そのデバイスコンテキストをメモリデバイスコンテキストにコンパチブルにする
wDC.CreateCompatibleDC(pDC) ;
CRect wRect;
GetClientRect(&wRect);// クライアント領域の大きさを得る

std::vector <COLORREF> wBuffer ;
CBitmap wBitmap ;

// ビットマップは、デバイスによって違うので、メモリデバイスコンテキス

// にコンパチブルなビットマップを生成する。
wBitmap.CreateCompatibleBitmap(pDC,wRect.right+1,wRect.bottom+1) ;
wDC.SelectObject(&wBitmap) ;

int x,y ;
for(y = wRect.top;y < wRect.bottom;y++) {
for(x = wRect.left;x < wRect.right;x++) {
//GetPixelのテストなので画面表示はされない
wDC.SetPixel(x,y,RGB(x%256,0,0)) ;
COLORREF wColor = wDC.GetPixel(x,y) ;
wBuffer.push_back(wColor) ;
}
}
}
ひとまず、これで動作しました。みなさん、ありがとうございました。
ただ、OnDraw()の引数になっているpDCをビットマップ化しようとすると、
GetPixel()はうまく動作しませんでした。
pDC->SelectObject(&wBitmap) ;とするとpDC->GetPixel(x,y)は、動作しませんでした。
(なぜだか、 よくわかりません???)


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

ちょっと気になったのですが、
> std::vector <COLORREF> wBuffer ;
これって有効なんですか?
vectorでCOLORREF等WIN32 API系の型を使った
例って見たことないのですが大丈夫ですか?
long等の型で定義して、キャストでCOLORREF
に変換するほうがいいと思ったのですが。


返信引用
ガラ
 ガラ
(@ガラ)
ゲスト
結合: 20年前
投稿: 201
Topic starter  

> std::vector <COLORREF> wBuffer ;
> これって有効なんですか?
特にエラーなく、動作も期待通りに動いたのですが・・・・
あんまり、よくなかったですか?


返信引用
麩
 麩
(@麩)
ゲスト
結合: 17年前
投稿: 95
 

>vectorとCOLORREF
STLガシガシ使うときにOSベッタリの型を使う事が少ないって程度で、何の問題
も無いと思います。
実際にもCOLORREFはDWORDのtypedefで、DWORDはunsigned longの
typedefなので、全く問題は無い筈です。

というかこんな事で問題が起きる様なAPIだと、そっちの方が大問題では。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

統一感の問題ではないかと。

非MFCでWin32 Applicationのプログラムを作る場合、
COLORREFを動的配列で持ちたいならば、
私もstd::vector<COLORREF>を使います。
麩さんの書いてある理由の通りで、キャストが必要とも思いません。

ただ、ガラさんのプログラムはMFCなので、動的配列にはMFCのCUIntArrayが使えます。
統一性を重んじるならば、CUIntArrayを使うほうが良いかもしれません。

# 個人的にはCArray系のクラスは使いなれないので、MFCでもstd::vectorを
# 使う場合があり、テスト用のプログラムなどではその選択が多いです。
# 皆さんはMFCとSTLを混ぜて使いますか?


返信引用
悠
 悠
(@悠)
ゲスト
結合: 17年前
投稿: 40
 

# 皆さんはMFCとSTLを混ぜて使いますか?
ケースバイケースでは?
取り敢えず…や、急ぎで…ならば、試行錯誤する時間よりも
(自身的に)使用経験の豊富な組み合わせで対処すると思われます。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> 実際にもCOLORREFはDWORDのtypedefで、DWORDはunsigned longの
> typedefなので、全く問題は無い筈です。

> 私もstd::vector<COLORREF>を使います。

ガラさんの問題の助けにならないかと思いました。
問題ないとのことでよかったです。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました