• 締切済み

画像の大きさと2次元配列

C++で ビットマップの一つ一つのピクセルの色を取得したいんですが、 画像を読み込んでHBITMAPにしてBITMAPにして、 COLORREF color[bitmap.bmWidth][bitmap.bmHeight]; と宣言するとエラーになってしまいます。 具体的には 『定数式が必要です。』や『サイズが 0 の配列を割り当てまたは宣言しようとしました。』です。

みんなの回答

回答No.3

> 二次元配列が宣言できないということです。 mallocで動的に確保せにゃなりません。

参考URL:
http://www2.realint.com/cgi-bin/tarticles.cgi?pointc+33050
hosepens
質問者

お礼

ぜんぜんわかってませんでした。 ありがとうございました。

  • chie65535
  • ベストアンサー率43% (8526/19383)
回答No.2

BITMAPのピクセルの色の取得は、そんなに簡単ではありません。 BITMAPのイメージデータの中身は「ピクセルのフォーマットごとに、データの形式が違う」ので「フォーマットに合わせた取り出し方」が必要になります。 例えば、インデックスカラーフォーマットの256カラーのビットマップでは、イメージデータは1バイト1ピクセルで、値は0~255のインデックス番号になっています。そして、0番のカラーは、0番のパレットカラーを見ないと、実際の色が判りません。 例えば、インデックスカラーフォーマットの16カラーのビットマップでは、イメージデータは1バイトの上位4ビット、下位4ビットの2つで2ピクセルになっていて、値は0~15のインデックス番号になっています。0番のカラーは、0番のパレットカラーを見ないと、実際の色が判りません。 なので、通常、Bitmapのピクセル取得はGetPixcelを使用します(GetPixcelは、ビットマップのフォーマットに合わせ、内部で色々な処理を行うので、とても遅い関数です。しかし、同じ事を自前で行うのは不可能に近いでしょう) http://msdn.microsoft.com/ja-jp/library/system.drawing.bitmap.getpixel(VS.80).aspx ビットマップのピクセルデータは、配列型でどうこうできるような簡単なシロモノではないので、素直にGetPixcelを使用しましょう。

hosepens
質問者

お礼

はい。 そうしたいとおもいます。 ありがとうございました。

回答No.1

で、質問は何ですか?

hosepens
質問者

お礼

質問をしっかりできるようにしたいと思います。

hosepens
質問者

補足

つまり、 二次元配列が宣言できないということです。 だから、解決方法を知りたいと思っています。

関連するQ&A

  • StretchBlt関数について

    StretchBlt関数について 画像を縮小して表示しようとしていますが、上手くいきません。 beforeはint型の変数で現在「0」が入っていますので、 無視していただきたいと思います。 まず、テストでStretchBlt関数で縮小しない状態で画面縦幅の中央に表示しようと 下記コードで試みましたが、横は問題ないようですが、 縦に拡大1.5倍くらい拡大されてしまいました。 int MyBitOpen(HWND hWnd,HDC hNormalDC,DataParam *data){ HBITMAP hBitmap; BITMAP bmpInfo={0}; HDC hBitDC; RECT rc; hBitDC=CreateCompatibleDC(NULL); hBitmap=(HBITMAP)LoadImage(NULL,data->szFile[data->iFileCount], IMAGE_BITMAP,0,0,LR_LOADFROMFILE); GetObject(hBitmap,sizeof(BITMAP),&bmpInfo); SelectObject(hBitDC,hBitmap); GetClientRect(hWnd,&rc); StretchBlt(hNormalDC,before+5,(rc.bottom-bmpInfo.bmHeight)/2, (before+5)+bmpInfo.bmWidth,((rc.bottom-bmpInfo.bmHeight)/2)+bmpInfo.bmHeight, hBitDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY); 関数から戻り BitBlt(hdc,0,0,rc.right,rc.bottom,hNormalDC,0,0,SRCCOPY); で画面出力しております。 これがうまくいかない理由もわかりませんが、 下記のように(1)StretchBltを使用せずBitBltに書き換えただけのものと (2)StretchBltを使用しても描画開始座標を(0、0)に変更したものは 拡大されず上手くいってしまいます。 (1) BitBlt(hNormalDC,before+5,(rc.bottom-bmpInfo.bmHeight)/2, (before+5)+bmpInfo.bmWidth,((rc.bottom-bmpInfo.bmHeight)/2)+bmpInfo.bmHeight, hBitDC,0,0,SRCCOPY); (2) StretchBlt(hNormalDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight, hBitDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY); 座標の取得は間違っていないと思うのですが・・ 本来は画面中央に縦横1/2に縮小した下記のコードでしたが まず上記がうまくいっていないので・・・ 初心者のためシンプルに書けませんでした↓ StretchBlt(hNormalDC,((before+5)+(bmpInfo.bmWidth/4)), (((rc.bottom-bmpInfo.bmHeight)/2)+(bmpInfo.bmHeight/4)), (((before+5)+bmpInfo.bmWidth)-(bmpInfo.bmWidth/4)), ((((rc.bottom-bmpInfo.bmHeight)/2)+bmpInfo.bmHeight)-(bmpInfo.bmHeight/4)), hBitDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY); ご教授よろしくお願いします。

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

    プログラムを始めたところの初心者です。 画像を透過し、ウインドウに表示させたいので、いろいろ探してみたところ、 マスクを自動で作成すると言う物があったので、参考にさせてもらいました。 さらに、その中に、『同じように透過済み画像を作れる』とあったので、いろいろ試したのですが、ダメでした・・・ よろしければ、やり方を教えていただけないでしょうか。 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

  • ActiveBasic 透過画像の作り方

    ゲームを作っています。 そのときに、背景を透過した画像を作る関数を書いたのですが、どうしてもうまく処理が出来ません。 Function CreateMask(hBmp As HBITMAP) As HBITMAP Dim hDC As HDC Dim hBaseDC As HDC,hBaseBmp As HBITMAP Dim hMaskDC As HDC,hMaskBmp As HBITMAP Dim hTempDC As HDC,hTempBmp As HBITMAP Dim hCompDC As HDC,hCompBmp As HBITMAP Dim bmp As BITMAP Dim dummy[5] As HBITMAP hDC=GetDC(hMainWnd) hBaseDC=CreateCompatibleDC(hDC) hMaskDC=CreateCompatibleDC(hDC) hTempDC=CreateCompatibleDC(hDC) hCompDC=CreateCompatibleDC(hDC) GetObject(hBmp,len(bmp),bmp) hMaskBmp=CreateCompatibleBitmap(hMaskDC,bmp.bmWidth,bmp.bmHeight) hBaseBmp=CreateCompatibleBitmap(hDC,bmp.bmWidth,bmp.bmHeight) hCompBmp=CreateCompatibleBitmap(hDC,bmp.bmWidth,bmp.bmHeight) dummy[0]=SelectObject(hTempDC,hBmp) dummy[1]=SelectObject(hMaskDC,hMaskBmp) dummy[2]=SelectObject(hBaseDC,hBaseBmp) dummy[3]=SelectObject(hCompDC,hCompBmp) SetBkColor(hTempDC,GetPixel(hTempDC,0,0)) BitBlt(hMaskDC,0,0,bmp.bmWidth,bmp.bmHeight,hTempDC,0,0,NOTSRCCOPY) BitBlt(hBaseDC,0,0,bmp.bmWidth,bmp.bmHeight,hTempDC,0,0,SRCCOPY) BitBlt(hBaseDC,0,0,bmp.bmWidth,bmp.bmHeight,hMaskDC,0,0,SRCAND) BitBlt(hMaskDC,0,0,bmp.bmWidth,bmp.bmHeight,hMaskDC,0,0,NOTSRCCOPY) BitBlt(hCompDC,0,0,bmp.bmWidth,bmp.bmHeight,hMaskDC,0,0,SRCAND) BitBlt(hCompDC,0,0,bmp.bmWidth,bmp.bmHeight,hBaseDC,0,0,SRCPAINT) SelectObject(hTempDC,dummy[0]) SelectObject(hMaskDC,dummy[1]) SelectObject(hBaseDC,dummy[2]) SelectObject(hCompDC,dummy[3]) DeleteDC(hTempDC) DeleteDC(hMaskDC) DeleteDC(hBaseDC) DeleteDC(hCompDC) CreateMask=hCompBmp End Function とりあえず、いろいろと実験したところ、 背景を黒くしたもの(hBaseDC)とマスク画像(hMaskDC)はちゃんと出来ています。 おそらく問題なのは、 BitBlt(hCompDC,0,0,bmp.bmWidth,bmp.bmHeight,hMaskDC,0,0,SRCAND) BitBlt(hCompDC,0,0,bmp.bmWidth,bmp.bmHeight,hBaseDC,0,0,SRCPAINT) ここではないかと思っています。 これを処理すると、背景を黒くしたもの(hBaseDC)と同じものが出てきます。 これを透過するにはどうしたらいいのでしょうか? ご教授お願いします。 Win.XP AB 4.23.00

  • 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); } なのですが、これはメインウィンドウでは動くのですが、ダイアログボックスでは動かずこまっています。 どうか、助言のほどよろしくお願いします。

  • ビットマップ画像表示

    いつもお世話になっております。 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関数は子ウィンドウを表示するときに実行されます。 全て載せられないので追加した部分のみプログラムを載せましたが、 この部分だけでも、プログラムの間違い等はありませんでしょうか。 ご教授お願いいたします。

  • ビットマップの表示ができません。

    Visual Studio.net 2003 MFCを使用しています。 ビットマップの表示とフォームのサイズ変更はできたのですが、 以下のソースのように フォームのサイズをビットマップのサイズに変更すると ビットマップが表示されません。 一瞬表示はされているようですが、 真っ白になります。 フォームをきちんとビットマップのサイズに変更し、 ビットマップを表示するにはどうすればいいでしょうか? int num=35; void CProject1View::OnLButtonUp(UINT nFlags, CPoint point) {   // TODO : ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。   char str[128];   wsprintf(str,"c:\\test\\%d.bmp",num);num++;   HBITMAP hbm = (HBITMAP)LoadImage(NULL, str, IMAGE_BITMAP,0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION );   CBitmap *pBmp = CBitmap::FromHandle( hbm );   BITMAP bmp;   GetObject(hbm,sizeof(bmp),&bmp );   CDC bmpdc;   CDC *mydc=GetDC();   bmpdc.CreateCompatibleDC(mydc);   CBitmap *pOldBmp = bmpdc.SelectObject(pBmp);   GetParentFrame()->SetWindowPos(&wndTop,0,0,bmp.bmWidth,bmp.bmHeight,SWP_NOMOVE);   mydc->BitBlt( 0, 0,bmp.bmWidth, bmp.bmHeight, &bmpdc, 0, 0, SRCCOPY );   bmpdc.SelectObject(pOldBmp);   DeleteObject(hbm);   CView::OnLButtonUp(nFlags, point); }

  • 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); } どこか改善点などありましたら、よろしくお願いいたします。

  • 画像表示について

    画像を表示させたいのですがうまくいきません。 途中まで打ってみたのでご意見お願いします。 (リソースから読み込んで表示させる方法) 環境:MicrosoftVisualC++ SDK ******省略********* case WM_PAINT:   hdc = BeginPaint(hWnd,&ps);   //ビットマップリソースハンドルの取得   hBmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1));   if(hBmp == NULL){     MessageBox(hWnd,"ファイルの読み込みに失敗しました。","エラー",MB_ICONWARNING | MB_OK);     exit(1);   }   //ビットマップの大きさの情報取得   GetObject(hBmp,(int)sizeof(BITMAP),&bmp_info);   w = bmp_info.bmWidth;   h = bmp_info.bmHeight;   hdc_mem = CreateCompatibleDC(hdc);   SelectObject(hdc_mem,hBmp);   BitBlt(hdc,0,0,w,h,hdc_mem,0,0,SRCCOPY);   DeleteDC(hdc_mem);   DeleteObject(hBmp);   EndPaint(hWnd,&ps);   break; ******リソース(img.rc)****** // // Bitmap // IDB_BITMAP1 BITMAP DISCARDABLE "bitmap1.bmp" #ifdef APSTUDIO_INVOKED

  • 丸いボタンの表示でCPU100%

    VC6.0でMFCアプリケーションを作成しています。 ・ダイアログベース ・背景はビットマップ(スタイルにWS_CLIPCHILDRENを追加) ・ボタンはビットマップ&非矩形(丸) これを作成し、実行するとCPU使用率が100%になってしまいます。 OnPaint()での描画をしなければ、ボタンが丸く表示されません。 ご存知の方は教えてください。 以下、ソース抜粋です。 メンバ CButton m_cbImage; CBitmap m_cBmpBack; CBitmap m_cBmpButton; HBITMAP m_hBmpBack; BITMAP m_bmp; HDC m_hDc; OnInitDialog(){ //背景ビットマップ m_cBmpBack.LoadBitmap(IDB_BITMAP_BACK); //ボタンビットマップ m_cBmpButton.LoadBitmap(IDB_BITMAP_BUTTON); HBITMAP hBmpButton = HBITMAP(m_cBmpButton); m_cbImage.SetBitmap(hBmpButton); // ウィンドウに関する情報を取得 // BMPサイズ取得 m_hBmpBack = HBITMAP(m_cBmpBack); GetObject(m_hBmpBack, sizeof(BITMAP), &m_bmp); // BMPデバイスコンテキスト作成 m_hDc = CreateCompatibleDC(NULL); // オブジェクトを選択する SelectObject(m_hDc, m_hBmpBack); // ボタン変形 CRect cRectButton; m_cbImage.GetClientRect(cRectButton); CRgn rgnButton; rgnButton.CreateEllipticRgn(cRectButton.Width() * 1 / 8, cRectButton.Height() * 1 / 8, cRectButton.Width() * 7 / 8, cRectButton.Height() * 7 / 8); m_cbImage.SetWindowRgn((HRGN)rgnButton, TRUE); } OnPaint(){ HDC hdc = ::GetDC(m_hWnd); BitBlt(hdc, 0, 0, (int)m_bmp.bmWidth, (int)m_bmp.bmHeight, m_hDc, 0, 0, SRCCOPY); ::ReleaseDC(m_hWnd, hdc); } 以上、よろしくお願いします。

  • ビットマップボタンを押したときの処理についてなんですが

    環境はVC++6.0 MFC ダイアログベースです。 MFC初心者なんですが、 HBITMAP hBitmap; hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), (LPCTSTR)csBMPFile,      IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); を使いビットマップハンドルをし取得しました。 ビットマップの貼り付けは出来たのですが、ボタンを押したときにビットマップの画像を変える処理の仕方がわかりません>< loadbitmapsなら容易に出来るのですが、どうしてもloadimageを使って表示したいのですが、どのようにすれば良いでしょうか? 御教授よろしくお願いします><