• 締切済み

bitmap画像の保存がうまくいきません。

VC++のMFC、ダイアログベースで画像処理のソフトを作っています。 処理した画像を保存したいのですが、「描画できませんでした」というメッセージのでるファイルになってしまい、うまく保存できません。 プログラムは以下のようになっていてピクチャーコントロールの変数をm_pict8にしています。また、画像は24ビットで240×320のものを保存します。 static LONG CalcScanLineByte(const LONG w, const WORD bpp) { return (((bpp * w) + 31) / 32) * 4; } //----------------------------------------------------------- void Cstart2Dlg::OnBnClickedButton10() //保存ボタン { CFileDialog myDLG(FALSE,"BMP","*.BMP",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"画像(*.BMP)|*.BMP||"); if(myDLG.DoModal() == IDOK){ CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate | CFile::modeWrite|CFile::typeBinary); //ピクチャボックスからビットマップを取り出す HBITMAP hBitmap = m_pict8.GetBitmap(); //無いので処理できない if(hBitmap == NULL)return; //ビットマップの情報を取る BITMAP bitmap = {0}; ::GetObject(hBitmap, sizeof(bitmap), &bitmap); //4バイト調整したスキャンラインのサイズ const int iScanLineByte = ::CalcScanLineByte(240, bitmap.bmBitsPixel); //const int iScanLineByte = ::CalcScanLineByte(bitmap.bmWidth, bitmap.bmBitsPixel); //ファイルヘッダとビットマップヘッダ BITMAPFILEHEADER bmfh = {sizeof(bmfh)}; BITMAPINFOHEADER bmif = {sizeof(bmif)}; //ビットマップである事を示す名称 bmfh.bfType = ('M' << 8) | 'B'; //イメージデータへのオフセットはファイルヘッダ+ビットマップヘッダ bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmif); //見ての通り bmif.biBitCount = 24; //24ビットの時はBI_RGBで固定 bmif.biCompression = BI_RGB; //常に1で固定 bmif.biPlanes = 1; //見ての通り bmif.biWidth = 240; bmif.biHeight= 320; //bmif.biWidth = bitmap.bmWidth; //bmif.biHeight= bitmap.bmHeight; //4バイト調整も含めた正確な合計バイトサイズが必要 bmif.biSizeImage = iScanLineByte * bmif.biHeight; //ファイルヘッダ→ビットマップヘッダの順番に書き出す fout.Write(&bmfh, sizeof(bmfh)); fout.Write(&bmif, sizeof(bmif)); //イメージデータをセーブする HDC hMemDC = ::CreateCompatibleDC(NULL); ::SelectObject(hMemDC, hBitmap); //yを縦幅-1から回転させないと上下逆転してしまう for(int y = bmif.biHeight - 1; y >= 0; --y) { //3バイトずつステップする for(int x = 0; x < iScanLineByte; x += 3) { const COLORREF cref = ::GetPixel(hMemDC, x / 3, y); //色素の位置関係をBGRにしないと赤と青の関係が逆転してしまう const BYTE arrBy[3] = {GetBValue(cref), GetGValue(cref), GetRValue(cref)}; //1ピクセル分(3バイト)書き出す fout.Write(arrBy, sizeof(arrBy)); } } ::DeleteDC(hMemDC); } どこか改善点などありましたら、よろしくお願いいたします。

みんなの回答

回答No.4

 こんばんは。補足頂きました。  はい。当方の方では、其のコードで書き込めています。  一応、環境を出して置きます。win2000sp4 vc6.0sp5です。  読み込み確認に使用したのは、御馴染みのMSペイントブラシとMSOfficeピクチャーマネージャーです。  う~む。では確認です。以下は通過出来ていますか。hBitmapの中がNULLではないでしょうか。  //無いので処理できない  if(hBitmap == NULL)return;  其の他、デバッガでステップトレースして、怪しいと思う部分はありませんでしょうか。 >>あとピクチャーコントロールの変数m_pict8はCStatic型でよろしかったでしょうか。  Cstart2Dlgのヘッダでm_pict8が何型で宣言されていますでしょうか。CStaticの派生クラス辺りでしょうか。  MFCですから、CStaticコントロールでタイプがビットマップになったものがピクチャーボックスではないでしょうか。  http://msdn.microsoft.com/ja-jp/library/b7w5x74z(VS.80).aspx  一応クラス階層図中にもCPictureBoxなるものは無い見たいです。  http://msdn.microsoft.com/ja-jp/library/ws8s10w4(VS.80).aspx

回答No.3

 こんばんは。補足頂きました。  はい、ありません。  と、言うのも、  //ビットマップの情報を取る  BITMAP bitmap = {0};  ::GetObject(hBitmap, sizeof(bitmap), &bitmap);  bitmap.bmWidth//横幅が入っている  bitmap.bmHeight//縦幅が入っている  bitmap.bmBitsPixel//ビット数が入っている  仮にビットマップが240x320x24であろうと1440x900x32であろうとGetObject()で情報を検出出来るからです(実際に前半で情報を検出しています)。  更に、度々すんません、「イメージデータをセーブする」の所を、以下に訂正して下さい。其のままですと縦横が奇数の時(241x319x24で確認)、正常にイメージデータが書けません。 //イメージデータをセーブする LPBYTE pBuf = (LPBYTE)::calloc(bmif.biSizeImage, 1); HDC hMemDC = ::CreateCompatibleDC(NULL); ::SelectObject(hMemDC, hBitmap); for(int y = bmif.biHeight - 1; y >= 0; --y) { for(int x = 0; x < bmif.biWidth; ++x) { const int pos = (x * 3) + (iScanLineByte * y); const COLORREF cref = ::GetPixel(hMemDC, x, bmif.biHeight - 1 - y); pBuf[pos + 0] = GetBValue(cref); pBuf[pos + 1] = GetGValue(cref); pBuf[pos + 2] = GetRValue(cref); } } ::DeleteDC(hMemDC); fout.Write(pBuf, bmif.biSizeImage); ::free(pBuf);

s0511146
質問者

補足

ご回答ありがとうございます。 変更点を直したのですが、やはりまだうまくいかないようです。すみません。 下が修正したプログラムです。 static LONG CalcScanLineByte(const LONG w, const WORD bpp) { return (((bpp * w) + 31) / 32) * 4; } //----------------------------------------------------------- void Cstart2Dlg::OnBnClickedButton10() { CFileDialog myDLG(FALSE,"BMP","*.BMP",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"画像(*.BMP)|*.BMP||"); if(myDLG.DoModal() == IDOK){ CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate | CFile::modeWrite|CFile::typeBinary); //ピクチャボックスからビットマップを取り出す HBITMAP hBitmap = m_pict8.GetBitmap(); //無いので処理できない if(hBitmap == NULL)return; //ビットマップの情報を取る BITMAP bitmap = {0}; ::GetObject(hBitmap, sizeof(bitmap), &bitmap); //4バイト調整したスキャンラインのサイズ const int iScanLineByte = ::CalcScanLineByte(bitmap.bmWidth, bitmap.bmBitsPixel); //ファイルヘッダとビットマップヘッダ BITMAPFILEHEADER bmfh = {(0)}; BITMAPINFOHEADER bmif = {sizeof(bmif)}; //ビットマップである事を示す名称 bmfh.bfType = ('M' << 8) | 'B'; //イメージデータへのオフセットはファイルヘッダ+ビットマップヘッダ bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmif); //このイメージファイルのサイズ(コレを追加) bmfh.bfSize = bmfh.bfOffBits + (iScanLineByte * bitmap.bmHeight); //見ての通り bmif.biBitCount = 24; //24ビットの時はBI_RGBで固定 bmif.biCompression = BI_RGB; //常に1で固定 bmif.biPlanes = 1; //見ての通り bmif.biWidth = bitmap.bmWidth; bmif.biHeight= bitmap.bmHeight; //4バイト調整も含めた正確な合計バイトサイズが必要 bmif.biSizeImage = iScanLineByte * bmif.biHeight; //ファイルヘッダ→ビットマップヘッダの順番に書き出す fout.Write(&bmfh, sizeof(bmfh)); fout.Write(&bmif, sizeof(bmif)); //イメージデータをセーブする LPBYTE pBuf = (LPBYTE)::calloc(bmif.biSizeImage, 1); HDC hMemDC = ::CreateCompatibleDC(NULL); ::SelectObject(hMemDC, hBitmap); for(int y = bmif.biHeight - 1; y >= 0; --y) { for(int x = 0; x < bmif.biWidth; ++x) { const int pos = (x * 3) + (iScanLineByte * y); const COLORREF cref = ::GetPixel(hMemDC, x, bmif.biHeight - 1 - y); pBuf[pos + 0] = GetBValue(cref); pBuf[pos + 1] = GetGValue(cref); pBuf[pos + 2] = GetRValue(cref); } } ::DeleteDC(hMemDC); fout.Write(pBuf, bmif.biSizeImage); ::free(pBuf); } ファイルは出来るのですが、0×0のファイルが出来てしまいます。ビットの深さは24ビットになっているようですが…。 あとピクチャーコントロールの変数m_pict8はCStatic型でよろしかったでしょうか。 たびたび本当に申し訳ないのですが、ご指導よろしくお願いいたします。

回答No.2

 こんにちは。  すんません、どうやらファイルサイズの設定が疎かになっていた様です。コレで如何にか成りませんか。 //以上同じ //ファイルヘッダとビットマップヘッダ BITMAPFILEHEADER bmfh = {0};//ココを変更 BITMAPINFOHEADER bmif = {sizeof(bmif)}; //ビットマップである事を示す名称 bmfh.bfType = ('M' << 8) | 'B'; //イメージデータへのオフセットはファイルヘッダ+ビットマップヘッダ bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmif); //このイメージファイルのサイズ(コレを追加) bmfh.bfSize = bmfh.bfOffBits + (iScanLineByte * bitmap.bmHeight); //以下同じ

s0511146
質問者

補足

早速のご回答ありがとうございます。 変更してやってみたのですがうまくいきませんでした。 自分なりに考えてみたのですが、 bitmap.bmWidthとbitmap.bmHeightを今回保存したい画像のサイズ240×320なので、 それぞれ240と320に変える必要はありませんでしょうか?

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

CalcScanLineByte( )関数が変じゃないですか 画像1行分のバイト数を求めるんですよね bppを8で割って1ピクセルのバイト数を求めそれと横幅のwをかけて1行分のバイト数を求める。 それを4バイト境界に調整。 でいいのでは。 static LONG CalcScanLineByte(const LONG w, const WORD bpp) { LONG line = w * ( bpp / 8 ); // 1行のバイト数 while (line & 3) line++; // 4バイト境界にそろえる return line; }

関連するQ&A

  • 画像の保存方法。

    VC++のMFC、ダイアログベースで画像処理のソフトを開発している者です。 ピクチャーコントロールに画像を表示させて、その画像を保存したいと思っています。 保存用のダイアログを開き、名前を付けて保存したいのですがうまくいきません。 下が今作っているプログラムです。 void Cstart2Dlg::OnBnClickedButton10() { CFileDialog myDLG(FALSE,"BMP","*.BMP", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "画像(*.BMP)|*.BMP||"); if(myDLG.DoModal() == IDOK){ CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate |CFile::modeWrite|CFile::typeBinary); UpdateData(TRUE); fout.WriteString(m_pict8); fout.WriteString("\xla"); filename = myDLG.GetPathName(); SetWindowText("start2"+filename); } ピクチャーコントロールの変数をm_pict8にしています。テキストファイルを保存するプログラムを参考にして作っているので間違っているのだと思います。 画像の保存方法が分かる方がいらっしゃいましたらよろしくお願いいたします。

  • ビットマップ画像表示

    いつもお世話になっております。 VS2005でC++を用いてWindowsアプリケーションの作成をしています。 子ウィンドウにビットマップ画像(ファイル名:HELP.bmp)を 表示させようとプログラムを組んだのですが、 子ウィンドウを出してもビットマップ画像が表示されません。 以下のようなプログラムを追加しました。 --------------------------------- ///リソーススクリプト/////////////////////////////////  IDB_BITMAP1  BITMAP DISCARDABLE  "HELP.bmp" ///ヘッダースクリプト/////////////////////////////////  #define IDB_BITMAP1   3000 ///ソーススクリプト/////////////////////////////////// void ShowMyBMP(HWND hWnd, HDC hdc){   HDC hmdc;   HBITMAP hBitmap;   BITMAP bmp;   HINSTANCE hInst;   int BMP_W, BMP_H;   hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);   hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));  //インスタンスハンドル取得   GetObject(hBitmap, sizeof(BITMAP), &bmp);  //ビットマップの情報を得る   BMP_W = (int)bmp.bmWidth;  //画像の幅   BMP_H = (int)bmp.bmHeight;  //画像の高さ   hmdc = CreateCompatibleDC(hdc);  //メモリデバイスコンテキストハンドルを取得   SelectObject(hmdc, hBitmap);   BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY);   StretchBlt(hdc, 0, BMP_H, BMP_W / 2, BMP_H / 2, hmdc, 0, 0, BMP_W, BMP_H, SRCCOPY);   DeleteDC(hmdc); //デバイスコンテキストハンドルを開放   DeleteObject(hBitmap);   return; } --------------------------------- ShowMyBMP関数は子ウィンドウを表示するときに実行されます。 全て載せられないので追加した部分のみプログラムを載せましたが、 この部分だけでも、プログラムの間違い等はありませんでしょうか。 ご教授お願いいたします。

  • WinAPIでの画像高速切り替え表示プログラム1

    WinAPIを使用して、ビットマップ画像を8枚読み込み、それを連続高速表示するプログラムを作成しています。 今はSetTimerを使ってWM_TIMERを受け取ったときに画像をInvalidateRect(再描画)しています。 以下のソースで動作はするのですが、WM_TIMERは整数ミリ秒でしか設定できず、精度も悪く優先順位も遅いようなので他の方法を考えています。 画像8枚を6.25msecで切り替えて表示するというのをESCAPEするまで繰り返したいのですが...。 リフレッシュレートは160Hzにあげています。 QueryPerformanceFrequencyというものを使えばいいのかなと思っていますが、どこでどう使えばいいのか、それをどう受け取って再描画すればいいのかわかりません。 どなたかご教授お願いします。ソースファイルを書いていただけたら嬉しいです。 #include<windows.h> #define BMP_SUM8//画像の総数 #define TIMER_ID (100) // 作成するタイマの識別ID #define TIMER_ELAPSE (6) // WM_TIMERの発生間隔 LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ HDC hdc; PAINTSTRUCT ps; HBITMAP hBitmap; int i; const char *filename[BMP_SUM]={"gazou0.bmp", "gazou1.bmp", "gazou2.bmp", "gazou3.bmp", "gazou4.bmp", "gazou5.bmp", "gazou6.bmp", "gazou7.bmp"}; static HDC hMemDC[BMP_SUM]; static BITMAP bmp; static int bmp_index;//現在の画像番号 LONG lResult; switch(uMsg) { case WM_CREATE: hdc=GetDC(hWnd); for(i=0;i<BMP_SUM;i++){ hBitmap=(HBITMAP)LoadImage(0,filename[i],IMAGE_BITMAP,0,0,LR_LOADFROMFILE); hMemDC[i]=CreateCompatibleDC(hdc); SelectObject(hMemDC[i],hBitmap); } GetObject(hBitmap,sizeof(BITMAP),&bmp); DeleteObject(hBitmap); ReleaseDC(hWnd,hdc); return 0; case WM_TIMER: if( wParam != TIMER_ID ) { break; // 識別IDが一致しないタイマメッセージはDefWindowProc()に任せる } if(++bmp_index >= BMP_SUM) bmp_index=0; for(i = 0; i < BMP_SUM; i++){ InvalidateRect( hWnd, NULL, FALSE ); } return 0; case WM_DESTROY: for(i=0;i<BMP_SUM;i++) DeleteDC(hMemDC[i]); PostQuitMessage(0); return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hMemDC[bmp_index],0,0,SRCCOPY); EndPaint(hWnd,&ps); return 0; case WM_KEYDOWN: switch((CHAR)wParam) { case VK_ESCAPE: for(i=0;i<BMP_SUM;i++) DeleteDC(hMemDC[i]); PostQuitMessage(0); //WM_QUITメッセージを出す return 0; } } return DefWindowProc(hWnd,uMsg,wParam,lParam); } 入りきらないので2つに分けます。 続きは「WinAPIでの画像高速切り替え表示プログラム2」を見てください。

  • スクリーンキャプチャしてBMPファイルに保存する方法を教えて下さい

    スクリーンキャプチャしてBMPファイルに保存する方法を教えて下さい. ダイアログでボタンを押したらスクリーンキャプチャして、それをBMPファイルで保存したいのですがうまく動作しません。 ダイアログ画面のサイズは、横 659 画素、縦 486 行です。 GetDIBits()で162行まではコピー出来るのですが、それ以上ではエラーを起こします。 クリップボードに貼り付ける処理は正常に動作しています。 どこがまずいのかを教えていただけたら嬉しいです。 よろしくお願い致します。 void Test::OnScreenSave() { HDC hScreenDC; HDC hMemDC; HBITMAP hMemBmp; int scrx, scry; int xsize,ysize; RECT rect; HBITMAP hOld; GetWindowRect(&rect); scrx = GetSystemMetrics(SM_CXSCREEN); scry = GetSystemMetrics(SM_CYSCREEN); hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL); xsize = rect.right -rect.left; ysize = rect.bottom - rect.top; hMemDC = CreateCompatibleDC(hScreenDC); hMemBmp = CreateCompatibleBitmap(hScreenDC, xsize, ysize); hOld = (HBITMAP)SelectObject(hMemDC, hMemBmp); BitBlt(hMemDC, 0, 0, xsize, ysize, hScreenDC, rect.left, rect.top, SRCCOPY); int nWid = (xsize * 3 + 3) & 0xfffffffc; int nBmp = nWid * ysize; LPBYTE p = new BYTE[nBmp + 54]; LPBYTE pImg = (LPBYTE)(p + 54); LPBITMAPINFO pInfo = (LPBITMAPINFO)(p + 14); pInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); pInfo->bmiHeader.biWidth=nWid; pInfo->bmiHeader.biHeight=ysize; pInfo->bmiHeader.biPlanes=1; pInfo->bmiHeader.biBitCount=24; pInfo->bmiHeader.biCompression=BI_RGB; // 非圧縮フォーマット BI_RGB = 0 SelectObject(hMemDC, hOld); // hMemBmpを非選択とする int lines = GetDIBits(hMemDC, hMemBmp, 0, 162, pImg, pInfo, DIB_RGB_COLORS); // 162ラインまではコピー出来るが、それ以上ではエラーとなる。 if(OpenClipboard() != 0){ EmptyClipboard(); SetClipboardData(CF_BITMAP, hMemBmp); // この処理は正常に実行されている CloseClipboard(); } DeleteDC(hMemDC); DeleteDC(hScreenDC); delete [] p; }

  • Win32APIを使って入力されたキーによって表示する画像を変えるプログラムについて

    Win32APIを使って入力されたキーによって表示する画像を変えるプログラムを今、VisualSutudio2005のVC++で作っている最中なのですが、 上手く画像が表示されず困っています。具体的には、キーボードからキーが入力されたらTranslateMessage関数でWM_CHARメッセージを送って、その値(wParam)をWM_CHARメッセージ内でTCHAR型の変数に代入し、InvalidateRect関数を使ってWM_PAINTメッセージを送って、再描画処理を行ってその中で、if(tchar == 'a') { hbitmap = (HBITMAP)LoadImage(NULL,BMP,IMAGE_BITMAP,0,0,LR_LOADFROMFILE); SelectObject(hMemdc,hbitmap); GetObject(hbitmap,sizeof(BITMAP),&bitmap); BitBlt(painthdc,0,0,350,467,hMemdc,0,0,SRCCOPY); } という処理をしてaが入力されたら読み込んだ画像を表示!という形にしたいのですが、実際ウィンドウには表示されなくて悩んでいます。わかりにくくて誠に申し訳ありませんが、どなたかどうかご教授願えないでしょうか。何卒よろしくお願い致します。

  • PrintScreenしたあとに画像を保存する方法

    LRESULT CALLBACK WndProcScreenCapture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { // MMTIME mm; // CommonClass Common; static int id,x,y; HDC hdc; PAINTSTRUCT ps; static HBRUSH hBrush; HWND desktop; RECT rc; static int width,height; static BITMAPINFO bmpInfo; static LPDWORD lpPixel; static HBITMAP hBitmap; static HDC hMemDC; FILE *fpt; int i,j; //clock_t start,end; switch (message) { case WM_CREATE: desktop=GetDesktopWindow();//デスクトップのハンドルを取得 GetWindowRect(desktop,&rc);//デスクトップのRECT情報を取得 width=rc.right; height=rc.bottom; //DIBの情報を設定する bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth=width; bmpInfo.bmiHeader.biHeight=height; bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biBitCount=32; bmpInfo.bmiHeader.biCompression=BI_RGB; //DIBSection作成 hdc=GetDC(hWnd); hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0); hMemDC=CreateCompatibleDC(hdc); SelectObject(hMemDC,hBitmap); ReleaseDC(hWnd,hdc); fopen_s(&fpt,"20090715.raw","wb"); fwrite((void**)&lpPixel[0],sizeof(unsigned char),width*height,fpt); /* DIBSectionにグラデーション描画 */ for (i = 0;i < height;i++) { for (j = 0;j <width;j++) { #if 0 /* DIBピクセル列に直接アクセス */ lpPixel[i + j * 256] = (i << 16); lpPixel[i + (j + 32) * 256] = (i << 8); lpPixel[i + (j + 64) * 256] = i; lpPixel[i + (j + 96) * 256] = (i << 16) | (i << 8) | i; /* GDI経由で描画 */ SetPixel(hMemDC, i, j + 128, RGB(i, 0, 0)); SetPixel(hMemDC, i, j + 128 + 32, RGB(0, i, 0)); SetPixel(hMemDC, i, j + 128 + 64, RGB(0, 0, i)); SetPixel(hMemDC, i, j + 128 + 96, RGB(i, i, i)); #endif } } //fwrite(&(bmpInfo.bmiHeader),sizeof(unsigned char),40,fpt); //fwrite((void**)&lpPixel,sizeof(unsigned char),width*height,fpt); //fwrite(&(bmpInfo.bmiColors),sizeof(unsigned char),width*height,fpt); fclose(fpt); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); break; case WM_DESTROY: //自らlpPixelを解放するべからず DeleteDC(hMemDC); DeleteObject(hBitmap); //BMPを削除した時、lpPixelも自動的に解放される PostQuitMessage(0); break; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); break; case WM_CHAR: の様に書いて、windowにキャプチャ画像を表示することは できたのですが、 この画像の画像情報のピクセルのポインタはどれなのでしょうか? 画像をraw形式でもいいので保存したいのですが、 どうしたら、キャプチャした画像を ファイルとして保存 できますか? //fwrite((void**)&lpPixel,sizeof(unsigned char),width*height,fpt); ではうまくいきませんでした。

  • 透過済み画像を作りたい

    プログラムを始めたところの初心者です。 画像を透過し、ウインドウに表示させたいので、いろいろ探してみたところ、 マスクを自動で作成すると言う物があったので、参考にさせてもらいました。 さらに、その中に、『同じように透過済み画像を作れる』とあったので、いろいろ試したのですが、ダメでした・・・ よろしければ、やり方を教えていただけないでしょうか。 http://oshiete1.goo.ne.jp/qa5254128.html 上を参考にさせていただきました Dim hDC as HDC, hTemp As HDC, hDest as HDC,hOriDC As HDC Dim hBmpTemp as HBITMAP, dummy(3) as HBITMAP,hOriBmp As HBITMAP Dim bmp as BITMAP Dim hMemDC As HDC,hMemBmp As HBITMAP hDC=GetDC(NULL) hTemp=CreateCompatibleDC(hDC) hDest=CreateCompatibleDC(hDC) hOriDC=CreateCompatibleDC(hDC) hMemDC=CreateCompatibleDC(hDC) ReleaseDC(NULL,hDC) ' 元画像の情報の取得 GetObject(hBmp,Len(bmp),bmp) ' モノクロBITMAPの生成 hBmpTemp=CreateCompatibleBitmap(hDest,bmp.bmWidth,bmp.bmHeight) hOriBmp=CreateCompatibleBitmap(hOriDC,bmp.bmWidth,bmp.bmHeight) hMemBmp=hBmp dummy(0)=SelectObject(hTemp,hBmp) dummy(1)=SelectObject(hDest,hBmpTemp) dummy(2)=SelectObject(hOriDC,hOriBmp) dummy(3)=SelectObject(hMemDC,hMemBmp) SetBkColor(hTemp,GetPixel(hTemp,0,0)) ' 背景マスクの生成 BitBlt(hDest,0,0,bmp.bmWidth,bmp.bmHeight,hTemp,0,0,SRCCOPY) 'スプライト BitBlt(hOriDC,0,0,bmp.bmWidth,bmp.bmHeight,hDest,0,0,NOTSRCCOPY) BitBlt(hOriDC,0,0,bmp.bmWidth,bmp.bmHeight,hTemp,0,0,SRCAND) '透過 BitBlt(hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,hDest,0,0,SRCAND) BitBlt(hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,hOriDC,0,0,SRCPAINT) ' HBITMAPの切り離し SelectObject(hTemp,dummy(0)) SelectObject(hDest,dummy(1)) SelectObject(hOriDC,dummy(2)) SelectObject(hMemDC,dummy(2)) ' HDCの後始末 DeleteDC(hTemp) DeleteDC(hDest) DeleteDC(hOriDC) DeleteDC(hMemDC) ' 呼び出し元への返り値 MakeMaskWith=hMemBmp

  • debugエラーについて

    VisualC++初心者です。 力を貸してください。 内容はDEBUG ERRORで Stack around the variable "rp" was corrupted Stack around the variable "res" was corrupted とでてしまいます。 構造体等は省略しました。 #include <stdio.h> #include <stdlib.h> #define N 8 typedef struct{ int maxi,maxj,akarusa[N][N]; unsigned char *data; }RESULT; int bunkatsu(BMP *rp,BMP *wp); int keisan(BMP *rp,BMP *wp); RESULT *max(RESULT *res); /* 画像の取込 */ int ReadHeader(BMP *p,FILE *fp){ unsigned int size; fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); fread(&p->Bmpf.bfType, sizeof(unsigned short), 1, fp); fclose(fp); exit(1); } fread(省略) return 0; } int ReadBmp(BMP *p,FILE *fp){ int dummy, byte, i, j, pixel; unsigned char *ReadBody=0; ReadHeader(p,fp); byte = p->Bmpi.biBitCount/8; dummy = (p->Bmpi.biWidth%4)?(4-(p->Bmpi.biWidth*byte)%4) : 0; pixel = ((p->Bmpi.biWidth)*byte+dummy)*p->Bmpi.biHeight; ReadBody = (unsigned char*)calloc(pixel,sizeof(char)); p->body = (unsigned char*)calloc(pixel,sizeof(char)); p->blue = (unsigned char*)calloc((pixel/byte),sizeof(char)); p->green = (unsigned char*)calloc((pixel/byte),sizeof(char)); p->red = (unsigned char*)calloc((pixel/byte),sizeof(char)); fread(ReadBody,1,pixel,fp); if(p->Bmpi.biBitCount == 8){ printf("\n"); for(j=0;j<p->Bmpi.biHeight;j++){ for(i=0;i<p->Bmpi.biWidth;i++){ p->blue[(p->Bmpi.biWidth+dummy)*j+i] =p->Rgbq[ReadBody[(p->Bmpi.biWidth+dummy)*j+i]].rgbBlue; p->green[(p->Bmpi.biWidth+dummy)*j+i] =p->Rgbq[ReadBody[(p->Bmpi.biWidth+dummy)*j+i]].rgbGreen; p->red[(p->Bmpi.biWidth+dummy)*j+i] =p->Rgbq[ReadBody[(p->Bmpi.biWidth+dummy)*j+i]].rgbRed; } } for(j=0;j<p->Bmpi.biHeight;j++){ for(i=0;i<p->Bmpi.biWidth;i++){ p->body[(p->Bmpi.biWidth+dummy)*j+i]=ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)+i]; } } } else if(p->Bmpi.biBitCount == 24 || p->Bmpi.biBitCount == 32){ for(j=0;j<p->Bmpi.biHeight;j++){ for(i=0;i<p->Bmpi.biWidth;i++){ p->blue[(p->Bmpi.biWidth+dummy)*j+i] = ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)*byte+i*byte]; p->green[(p->Bmpi.biWidth+dummy)*j+i] = ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)*byte+i*byte+1]; p->red[(p->Bmpi.biWidth + dummy)*j+i] = ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)*byte+i*byte+2]; } } } else{ printf("失敗\n"); exit(1); } free(ReadBody); return 0; } /* 480×480にする */ int bunkatsu(BMP *rp,RESULT *res){ int x,y,a=0; for(y=0;y<rp->Bmpi.biHeight;y++){ for(x=79;x<rp->Bmpi.biWidth-80;x++){ res->data[a] = rp->blue[y*rp->Bmpi.biWidth+x]+rp->green[y* rp->Bmpi.biWidth+x]+rp->red[y*rp->Bmpi.biWidth+x]; a++; } } return 0; } /* ブロック分けして各ブロックの明るさを計算する */ int keisan(BMP *rp,RESULT *res){ int b,c,x,y,i=0,j=0; for(y=0;(y+60)<rp->Bmpi.biHeight;y+=60){ for(x=0;(x+60)<(rp->Bmpi.biWidth-160);x+=60){ for(b=0;b<60;b++){ for(c=0;c<60;c++){ res->akarusa[i][j]+=res->data[(y+b)*rp->Bmpi.biWidth+(x+c)]; } } j++; } i++; } max(res); return 0; } /* 一番明るいブロックの特定 */ RESULT *max(RESULT *res){ int MAX1=0,MAX2=0,i=0,j=0; for(i=0;i<8;i++){ for(j=0;j<8;j++){ printf("[%d][%d]=%d",i+1,j+1,res->akarusa[i][j]); if(MAX1<res->akarusa[i][j]){ MAX1=res->akarusa[i][j]; res->maxi=i; res->maxj=j; } } printf("\n"); } printf("一番明るいブロックは[%d][%d]です\n",res->maxi+1,res->maxj+1); return 0; } int main(void){ BMP rp={0}; RESULT res={0}; FILE *fp; /* 画像の取り込み */ fp=fopen("LED1.bmp","rb"); ReadBmp(&rp,fp); res.data = (unsigned char*)calloc(rp.Bmpi.biWidth*rp.Bmpi.biHeight,sizeof(char)); fclose(fp); fp=0; bunkatsu(&rp,&res); keisan(&rp,&res); return 0; } です。よろしくお願いします。

  • c言語を使いダイアログにbmpを表示したい 

    はじめまして、 私は、c言語は初心者なのでが、ダイアログボックスに、画像(bmp)が表示することができません。 ソースは、 hdc = BeginPaint(hDlg, &ps); //指定ウィンドウ内での描写準備 // ビットマップをファイルからロードする hBitmap = ::LoadBitmap( NULL, _T("test.bmp") ); // ウィンドウのデバイスコンテキストハンドルを取得する hDC = GetDC( hDlg ); // メモリデバイスコンテキストを作成する hCompatDC = CreateCompatibleDC( hDC ); // ロードしたビットマップを選択する GetObject(hBitmap, sizeof(BITMAP), &bmp); // ビットマップをウィンドウに転送する(表示する) if(hBitmap != NULL){ StretchBlt( hDC, 0, 0, 100, 100, hCompatDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY ); SendDlgItemMessage( hDlg, IDC_STATIC, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); } なのですが、これはメインウィンドウでは動くのですが、ダイアログボックスでは動かずこまっています。 どうか、助言のほどよろしくお願いします。

  • ビットマップの描画について(Windowプログラミング)

    おせわになります。 現在WIndows上で動作するソフトを作成しています。 ほとんど作成は終わっているのですが、作成したWindowsの上にビットマップを描画する部分で不安な点があります。 (これまであまり手をつけていなかったので) ネットなどを参考に作成したのですが、サンプルコードを見ていただいておかしいところを指摘していただければ幸いです。 以下のようなコードになります。 int ShowBMP(HWND hWnd, HDC hdc) { HDC hmdc; HBITMAP hBitmap; BITMAP bmp; HINSTANCE hInst; int BMP_W, BMP_H; hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hBitmap = LoadBitmap(hInst, "TOPBMP"); GetObject(hBitmap, sizeof(BITMAP), &bmp); BMP_W = (int)bmp.bmWidth; BMP_H = (int)bmp.bmHeight; hmdc = CreateCompatibleDC(hdc); SelectObject(hmdc, hBitmap); BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY); DeleteDC(hmdc); DeleteObject(hBitmap); return 1; }

専門家に質問してみよう