初めまして!
実はちょっと困っていることがありまして掲示板でスレッドを立てさせてもらいました。
質問内容はVisualCのMFCを使って、1つのフォルダ内にある複数枚のビットマップを順に1枚
ずつ読みこむことです。
普段はビットマップをVisualcで表示する時はツールバー内の『挿入』からリソースとしてID
を登録するのですが、今回ではダイアログのようなボタンを用意し、押すことで任意にフォルダ
を選択して、Windowの中でそのフォルダ内にある全てのビットマップを1枚ずつ、全て表示でき
るようにしたいと考えています。
開発環境はwin98のVisualC++6.0です
どういう風にすればいいのか皆目見当がつきません…
どうかよろしくお願いします。
・・・で、結局わからないのは
・任意のフォルダの選択方法
・フォルダ内にある全てのビットマップファイルの取得方法
・ビットマップファイルのウィンドウ(あるいはダイアログ?)への表示方法
ですか?
すいません…。質問したいことがうまく書けてなくてわかりづらかったですね。
>・任意のフォルダの選択方法
>・フォルダ内にある全てのビットマップファイルの取得方法
>・ビットマップファイルのウィンドウ(あるいはダイアログ?)への表示方法
まとめると暇人貴子さんの言う通り上の3つです。希望する処理手順の流れもその通りです。
ビットマップの表示はウィンドウの中でと考えています。
よろしくお願いします
まずは以下のキーワード辺りから調べてみては。
>・任意のフォルダの選択方法
SHBrowseForFolder
>・フォルダ内にある全てのビットマップファイルの取得方法
CFileFind
>・ビットマップファイルのウィンドウ(あるいはダイアログ?)への表示方法
LoadImage,CStatic::SetBitmap,CBitmap,CDC::DrawState,...
どう表示するかによっていろいろ
dairygoodsさん、ありがとうございます。それで検索をかけてみます。
すいません、もう1つ質問してよろしいでしょうか?
先の質問は連続してビットマップを表示するという質問内容でしたが、今度はビットマップは
表示せずに、そのビットマップの1ピクセルごとのRGBを調べて色情報としてテキストファイル
に保存していきたいのですが、方法がわかりません。
ビットマップを表示してから1ピクセルごとに色情報を調べる方法はわかるのですが、いざ表
示せずにピクセルを調べるとエラーになります。
今書いているプログラムはこのようなものです。
…
CBitmap *oldBMP=myDC.SelectObject(&myBMP);
pDC->BitBlt(10,10,10+width,10+height,&myDC,0,0,SRCCOPY);
myDC.SelectObject(oldBMP);
for(y=0; y<height; y++)
{
for(x=0; x<width; x++)
{
color=pDC->GetPixel(10+x,10+y);
r=GetRValue(color); g=GetGValue(color); b=GetBValue(color);
fprintf(fp,(%d,%d,%d),r,g,b);
}
}
…
これで、表示せずにRGB値を取ろうとして、メモリ上の画像データを表示しないように
//pDC->BitBlt(10,10,10+width,10+height,&myDC,0,0,SRCCOPY);
と単純にコメントアウトしたのですが、そうするとRGB値が取れなくなってしまいました…
恐らくデバイスコンテキストの表示画面からじかにRGB値を取ってきているようなので失敗し
たのだと思います。
なんとかビットマップは表示せずにRGB値を取る方法を教えてください!
まったく初心者なのです。どうかお願いします。
BITMAPの画像データのみを得たいのならば、
ファイルから直接読み込んだらどうでしょうか?
BITMAPFILEHEADER
BITMAPINFOHEADER
上の構造体を CFileで読み込んで、データの位置を探して、
データだけを頂いてしまうわけです。
扱うビットマップの色数が限られていれば
そんなに手間ではないと思います。
NTAKAさんのコメントを参考にサイトや文献を調べなおしました。
『新VisualC++6.0入門 シニア編』に使えそうなソースがあったので自分なりに付け足してみ
ました。これの元はダイアログで好きなビットマップを読みこんでそのまま表示するというソー
スです。
char* m_BmpImage;
LPBITMAPINFO m_BmpInfo;
BITMAPFILEHEADER m_BmpFileHdr;
CFile file;
BITMAPINFOHEADER myBmpInfoHdr;
FILE *fp=fopen(log.txt,w); //実データ部分を書きこむファイル
CFileDialog myDLG(TRUE,NULL,NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,ビットマップ(*.BMP)|*.BMP||);
if(myDLG.DoModal()!=IDOK) return;
filename=myDLG.GetPathName();
if(!file.Open(filename,CFile::modeRead|CFile::typeBinary))
{ return; }
file.Read(&m_BmpFileHdr,sizeof(BITMAPFILEHEADER));
file.Read(&myBmpInfoHdr,sizeof(BITMAPINFOHEADER));
if(myBmpInfoHdr.biBitCount >=16)
m_BmpInfo=(LPBITMAPINFO)new char[sizeof(BITMAPINFO)];
else
{
m_BmpInfo=(LPBITMAPINFO)new char[sizeof(BITMAPINFOHEADER)]+
(1<<myBmpInfoHdr.biBitCount)*sizeof(RGBQUAD);
file.Read(m_BmpInfo->bmiColors,(1<<myBmpInfoHdr.biBitCount)*sizeof(RGBQUAD));
}
m_BmpInfo->bmiHeader=myBmpInfoHdr;
file.Seek(m_BmpFileHdr.bfOffBits,CFile::begin);//実データ部分から始めるようにする
m_BmpImage=new char[m_BmpFileHdr.bfSize - m_BmpFileHdr.bfOffBits];
file.Read(m_BmpImage,m_BmpFileHdr.bfSize - m_BmpFileHdr.bfOffBits);
///////// ファイルに書き出し /////////////
fprintf(fp,%s,*m_BmpImage);
fclose(fp);
////////////////////////////////////////
file.Close();
個人的に書いたところはC言語の部分だけです…。実行してみると、log.txtには期待した結果
であるrgbが書きこまれてなく(null)しか入ってなかったです。
おそらく256色のビットマップならいけるんだと思いますが、16~24bitだと格納されている情報が
スペクトルのようなのらしいので上手くいかないのかも…
うーん、困った…
こんな感じかな???
CBitmap *oldBMP=myDC.SelectObject(&myBMP);
for(y=0; y<height; y++)
{
for(x=0; x<width; x++)
{
color=myDC.GetPixel(10+x,10+y);
r=GetRValue(color); g=GetGValue(color); b=GetBValue(color);
fprintf(fp,(%d,%d,%d),r,g,b);
}
}
myDC.SelectObject(oldBMP);
> //pDC->BitBlt(10,10,10+width,10+height,&myDC,0,0,SRCCOPY);
myDCからpDCへのコピーを止めておいて、
> color=pDC->GetPixel(10+x,10+y);
コピー先から情報を採ろうというのは無理な話でしょう。
NEG(ねぐ) さんの書いた通りコピー元からRGBを取得すればよいです。
ファイルから読み込んだビットデータはbiBitCountの値によって
形式が違うので、それを判別して取得するのはお勧めしません。
みなさん、ありがとうございました!!
みなさんのおかげで実現できました! ほんとに助かりました!
近くにVC詳しい人がいなくて孤独にやっているので、レスを頂けて本当に心強かったです。
なにぶん、右も左もわからない初心者なので、またこちらでお世話になるかもしれませんが、そ
の時またよろしくお願いします
それでは。