• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Win32でのBITMAP)

Win32でのBITMAPの色情報取得方法について

このQ&Aのポイント
  • BITMAPをバイナリデータから作成する際の色情報取得方法について質問があります。
  • BITMAPのbiBitcountに基づいてカラーテーブルの色情報を取得する方法を試していますが、8Bit(256色)の場合に正しく動作するか疑問です。
  • また、4Bitの場合には16色となり、1バイト=2ピクセルとなるため、別の方法が必要なのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんばんは。  カラーテーブルと言う事はパレットの事でしょうか。でしたら、「8, 4, 1」bitの何れであっても、質問に記載されている手段で問題無いと思います。  実はpbmpInfo->bmiHeader.biClrUsedに使用されているパレット個数が記述されています。  しかし、本来なら記述するべきなのですが、記述する事を放棄しているアプリも存在するので(事もあろうかMSペイント)、(1 << pbmpInfo->bmiHeader.biBitCount)とした方が良いかもしれません。以下はbmpファイルを開いてパレットを出力します。参考程度に。 #include<windows.h> #include<stdio.h> int main() { HANDLE hFile = NULL; LPBYTE pBuffer = NULL; try { hFile = ::CreateFile("test.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL); if(hFile == INVALID_HANDLE_VALUE) throw("file open error"); DWORD dwComplete = 0; const DWORD dwSize = ::GetFileSize(hFile, NULL); if(dwSize < sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)) throw("file is wrong"); pBuffer = static_cast<LPBYTE>(::malloc(dwSize)); if(pBuffer == NULL) throw("out of memory"); ::ReadFile(hFile, pBuffer, dwSize, &dwComplete, NULL); BITMAPINFO* pbmpInfo = reinterpret_cast<BITMAPINFO*>(&pBuffer[sizeof(BITMAPFILEHEADER)]); if( pbmpInfo->bmiHeader.biBitCount != 8 && pbmpInfo->bmiHeader.biBitCount != 4 && pbmpInfo->bmiHeader.biBitCount != 1) throw("no palette"); int paletteLen = pbmpInfo->bmiHeader.biClrUsed; if(paletteLen == 0) paletteLen = 1 << pbmpInfo->bmiHeader.biBitCount; for(int l = 0; l < paletteLen; l++) { printf("bmpInfo.bmiColors[%d].rgbBlue = %d\n",l,pbmpInfo->bmiColors[l].rgbBlue); printf("bmpInfo.bmiColors[%d].rgbGreen = %d\n",l,pbmpInfo->bmiColors[l].rgbGreen); printf("bmpInfo.bmiColors[%d].rgbRed = %d\n",l,pbmpInfo->bmiColors[l].rgbRed); } } catch(LPCSTR pszErr) { printf("error : %s\n", pszErr); } ::free(pBuffer); ::CloseHandle(hFile); return 0; }

dotneer
質問者

お礼

実に分かりやすい説明をして貰えて嬉しいです。 8bitでも4bitでも関係ないんですね。 早速試してみようと思います。  全ソースを載せてくださってありがとうございます。

dotneer
質問者

補足

 実はまだBITMAP構造には疑問を持っているところがあり、全てを把握してないせいか上記でのソースで理解できないところがあるので質問なんですが、 BITMAPINFO* pbmpInfo = reinterpret_cast<BITMAPINFO*>(&pBuffer[sizeof(BITMAPFILEHEADER)]); でLPBYTEのアドレスを渡しているのですが、何故sizeof(BITMAPFILEHEADER)]);なんですか?pBufferの大きさはファイルサイズ分ですよね?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.2

 こんばんは。補足頂きました。  pBufferはファイルを丸ごと吸い上げた状態です。  バッファ内のBITMAPINFO情報がある位置へ移動する為に、バッファの先頭からBITMAPFILEHEADERのサイズ分だけずらさなければいけません。  ↓ファイル内の構造  BITMAPFILEHEADER  BITMAPINFOHEADER(BITMAPINFO::bmiHeader)//この位置に移動する為  ある場合はカラーテーブル[1~255](BITMAPINFO::bmiColors[1~255])※配列は0を基準  ビットイメージ

dotneer
質問者

お礼

BITMAPINFO情報ある場所まで配列を移動させ、そこからカラーパレットの情報を読み上げるんですね。  分かりました。 補足の回答ありがとうございます。  ネットで調べてたんですがよく分からなかったんで質問してみました。答えてくれる人がいて助かりました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • SetDIBitsToDeviceで88x31のpngを

    表示しようとして int SetDIBitsToDevice( HDC hdc, int XDest,←0 int YDest,←0 DWORD dwWidth,←88 DWORD dwHeight,←31 int XSrc,←0 int YSrc,←0と31でトライ UINT uStartScan,←0 UINT cScanLines,←31 CONST VOID *lpvBits,←読み込んだpngのfufferポイ CONST BITMAPINFO *lpbmi,←&bmpInfo UINT fuColorUse←DIB_RGB_COLORS ); としました。ただし BITMAPINFO bmpInfoは bmpInfo.bmiHeader.biSize=40; bmpInfo.bmiHeader.biWidth=88; bmpInfo.bmiHeader.biHeight=31; bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biBitCount=0; bmpInfo.bmiHeader.biCompression=BI_PNG; bmpInfo.bmiHeader.biSizeImage=pngのbufferのsize; bmpInfo.bmiHeader.biXPelsPerMeter=0; bmpInfo.bmiHeader.biYPelsPerMeter=0; bmpInfo.bmiHeader.biClrUsed=0; bmpInfo.bmiHeader.biClrImportant=0; と定義しました。 (実際にdivファイルを表示できていたプログラムの関連部分の書き換え) が、絵がでません。 どの設定に問題があるのでしょうか?

  • bmpファイルの画像データ表示

    C言語で24bit Windowsbitmapの画像データ部を読み込んで10進数でダンプするプログラムを書きましたが000…と表示されます. バイナリファイルの扱いは初めてなので勘違いを多々しているとおもいます.ご指導,ご指摘宜しくお願いします. =======ソース=========================== #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[]){ FILE *fp; char buff[40]; char buffData[2560]; size_t size = 1; size_t n = 40; int biSize; int biBitCount; int biCompression; int biWidth; int biHeight; int bfSize; int bfOffBits; int lineByte; int i; int position; int line; if( argc != 2){ printf("Run this way !! %s [bit map image] \n",argv[0]); return 0; } fp = fopen(argv[1],"rb"); if(fp == NULL){ printf("%s No such file or directory !!\n",argv[1]); return 0; } /********************************* * check header infomation * *********************************/ // check input file type fread(buff,size,n,fp); if('B' != buff[0] || 'M' != buff[1]){ printf("## Warning ## %s is not bit map file !!\n",argv[1]); return 0; } // check bitmap type biSize = *(int*)(buff + 14); if( biSize != 40){ printf("%s isn`t Windows bitmap !!\n",argv[1]); return 0; } // check the size(bit) of 1 pixel biBitCount = *(int*)(buff + 28); if(biBitCount != 24){ printf("%s isn't 24bit Windows bitmap !!\n",argv[1]); return 0; } // check the type of compression biCompression = *(int*)(buff + 30); if(biCompression != 0){ printf("%s is compressed Windows bitmap !!",argv[1]); return 0; } // check the width of image (pixel) biWidth = *(int*)(buff + 18); //printf("Width : %d\n",biWidth); // check the height of image (pixel) biHeight = *(int*)(buff + 22); //printf("Height : %d\n",biHeight); // check the file size bfSize = *(int*)(buff + 2); // check the offset to image data bfOffBits = *(int*)(buff + 10); /************************************ * reading image data * ************************************/ // the size of one line lineByte = (biWidth * biBitCount) / 8; printf("LineByte = %d\n",lineByte); for(i=0;i < biHeight ;i++){ position = bfOffBits + lineByte * (biHeight - (i + 1)); fseek(fp,position,SEEK_SET); fread(buffData,line,1,fp); printf("%d\n",*(int*)buffData); } fclose(fp); return 0; } ========================================

  • MFC - ダイアログボックスのPictureControlへの画像表示

    はじめまして。 現在MFCにおいて、ダイアログ形式のアプリケーションを作成しています。環境はVisual Studio 2005になります。 内容はWebカメラからのキャプチャを行い、そのキャプチャされた画像をダイアログ上に配置したPictureControlへ表示するというものです。 キャプチャされた画像は、1チャネルのグレースケールでありunsigned char型の1次元配列で格納されています。よってビットマップとして表示するには自身で構造体BITMAPINFOを作成しなければなりません。現状以下のように作成したのですが、うまく表示されません。 画像サイズは 320×240 です。 PictureControlのIDを IDC_BITMAP と設定し、 画素情報が格納されている配列を m_pbit とします。 int i; CWnd *pWnd = GetDlgItem( IDC_BITMAP ); CDC *Capt = pWnd->GetDC(); BITMAPINFO bmif; bmif.bmiHeader.biBitCount   =8; bmif.bmiHeader.biClrImportant =0; bmif.bmiHeader.biClrUsed    =256; bmif.bmiHeader.biCompression  =0; bmif.bmiHeader.biHeight     =240; bmif.bmiHeader.biPlanes     =1; bmif.bmiHeader.biSize      =sizeof(BITMAPINFOHEADER); bmif.bmiHeader.biSizeImage   =320*240; bmif.bmiHeader.biWidth     =320; bmif.bmiHeader.biXPelsPerMeter =0; bmif.bmiHeader.biYPelsPerMeter =0; for(i=0; i<256; i++){  bmif.bmiColors[i].rgbBlue = i;  bmif.bmiColors[i].rgbGreen = i;  bmif.bmiColors[i].rgbRed  = i;  bmif.bmiColors[i].rgbReserved = 0; } SetDIBitsToDevice(Capt->m_hDC, 0, 0, 320, 240, 0, 0, 0, 240, m_pbit, &bmif, DIB_RGB_COLORS); グレースケール画像なので配列bmiColorsは全て同色としました。 また、PictureControlのTypeをオーナ描画など全てのTypeを試しましたが、表示されませんでした。 必ずPictureControlに描画しなければならないという決まりはないのですが、ダイアログボックスにビットマップを表示するにはPictureControlだと考え、それに表示するようプログラムを組みました。 画素情報(グレースケールの輝度情報)のみ既知である状態からビットマップをダイアログに表示するためには他に方法があるのでしょうか? 上記のプログラムにおける間違い、またその他の方法についてアドバイスを頂けたらと思います。 よろしくお願いいたします。

  • PrintScreenKey押下でメモリはどこで取得?

    PrintScreenKey押下で mspaint(画像処理ソフト)で「貼り付け」をすると 画像が張り付けられますが、この過程をプログラミングしたいのですが どうしたらいいですか? どのようにOSメモリに保存された画像ポインタの先頭を取得 できますか? PrintScreenKeyをプログラミングするのは以下の様になるのは 知っています。 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,"ScreenCapture.bmp","wb"); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); BITMAPINFOHEADER bmih; BITMAPFILEHEADER bmfh; //RGBQUAD rgbquad; DWORD filesize,bmfhsize,bmihsize,rgbquadsize; bmfhsize=sizeof(bmfh); bmihsize=sizeof(bmih); //rgbquadsize=sizeof(rgbquad); filesize=bmfhsize+bmihsize+width*height; ::ZeroMemory(&bmfh, bmfhsize); ::ZeroMemory(&bmih, bmihsize); bmfh.bfType=0x4d42; bmfh.bfSize=filesize; bmfh.bfReserved1=0; bmfh.bfReserved2=0; bmfh.bfOffBits=bmfhsize+bmihsize; bmih.biSize=bmihsize; bmih.biWidth=width; bmih.biHeight=height; bmih.biPlanes=1; bmih.biBitCount=32; bmih.biClrUsed=2; bmih.biCompression=BI_RGB;//無圧縮形式 bmih.biSizeImage=0;//BI_RGBをセットした場合、0が好ましいとMSDNに書いてあった。 bmih.biXPelsPerMeter=0; bmih.biYPelsPerMeter=0; bmih.biClrImportant=0; fwrite(&bmfh,sizeof(unsigned char),bmfhsize,fpt); fwrite(&bmih,sizeof(unsigned char),bmihsize,fpt); fwrite(lpPixel,sizeof(DWORD),width*height,fpt);

  • 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); ではうまくいきませんでした。

  • 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); ご教授よろしくお願いします。

  • AndroidのBitmapのロードについて

    はじめまして 今OPENGLESで文字の描画を行っているのですが、何度も読み込んで解放してを繰り返していると なぜかアプリが警告なしで 強制終了します。 バイト数を抑えると一応ロードは可能なのですが、これでは文字を動的に表示できなくてこまっています。 以下がロードする文字列です public void textload(String[] str,int x,int y, int size){ // Log.v("デバッグ","ロード開始"); GL10 gl = glGraphics.getGL(); int[] textureIds = new int[1]; gl.glGenTextures(1, textureIds, 0); textureId = textureIds[0]; /** * 空のビットマップを作成し、そこへ文字を書き込むことでGL上に描画を行う。 */ //ビットマップの数値を計算 Log.v("デバッグ","ビットマップロード"); bitmap = Bitmap.createBitmap(640,480, Config.ARGB_4444); canvas = new Canvas(bitmap); Paint paint = new Paint(); Log.v("デバッグ","完了"); paint.setColor(Color.WHITE); paint.setStyle(Style.FILL); paint.setTextSize(size); canvas.drawColor(0); for(int i=0;i<str.length;i++){ if(str[i] != null){ canvas.drawText(str[i], x, y + size*(i+1), paint); } } width = bitmap.getWidth(); height = bitmap.getHeight(); gl.glEnable(GL10.GL_TEXTURE_2D); Log.v("デバッグ","ビットマップをtexImage2Dに"); // ! テクスチャ情報の設定 gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); //setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); Log.v("デバッグ","完了"); // ! bitmapを破棄 Log.v("デバッグ","解放処理開始"); if(bitmap !=null){ bitmap.recycle(); bitmap = null; } Log.v("デバッグ","解放処理完了"); //Log.v("デバッグ","ロード完了"); } かなり困っています・・・ どなたかご教授お願いします・・・

    • ベストアンサー
    • Java
  • windowsのアプリケーションを作っているのですがどうにもうまくコン

    windowsのアプリケーションを作っているのですがどうにもうまくコンパイルできず困っています。 キャスト演算子かポインタ関係だと思うのですがいろいろ変えてみてもうまくいきませんでした。 私は朝までしかいられないため起きておられる方ですぐに答えられる方がいれば具体的にどうしたらできるようになるか答えていただけますでしょうか? 今日を逃したら大体、一ヶ月先に反応すると思うのでよろしくお願いします。 以下エラー部分です。 LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) { HDC hdc,hdcWin; PAINTSTRUCT ps; int i,j; switch(iMsg){ case WM_CREATE: lpDIB=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BITMAPINFO)+E*F); lI=(LPBITMAPINFO)lpDIB; for(i=0;i<F;i++){ alpPixel[i]=(LPDWORD)(lpDIB+sizeof(BITMAPINFO)+E*i); } lI->bmiHeader.biSize =sizeof(BITMAPINFOHEADER); lI->bmiHeader.biWidth =B; lI->bmiHeader.biHeight =-B; lI->bmiHeader.biPlanes =1; lI->bmiHeader.biBitCount =B; lI->bmiHeader.biCompression =BI_RGB; for(i=0;i<D;i++){ *(alpPixel[0]+i)=0x00ff0000; *(alpPixel[1]+i)=0x0000ff00; *(alpPixel[2]+i)=0x000000ff; *(alpPixel[3]+i)=0x0000ffff; *(alpPixel[4]+i)=0x00ffffff; } hdc=GetDC(hwnd); hBMP=CreateCompatibleBitmap(hdcWin,C,C); hdcBMP=CreateCompatibleDC(hdc); hOldBMP=(HBITMAP)SelectObject(hdcBMP,hBMP); for(i=0;i<A;i++){ for(j=0;j<A;j++){ StretchDIBits(hdcBMP,j*B,i*B,B,B, 0,0,B,B,alpPixel[map[j+i*A]], lI,DIB_RGB_COLORS,SRCCOPY); } } ZeroMemory(&biInfo,sizeof(BITMAPINFO)); lI->bmiHeader.biSize =sizeof(BITMAPINFOHEADER); lI->bmiHeader.biWidth =C; lI->bmiHeader.biHeight =-C; lI->bmiHeader.biPlanes =1; lI->bmiHeader.biBitCount =B; lI->bmiHeader.biCompression =BI_RGB; ○ hBMP2=CreateDIBSection(hdc,&biInfo,DIB_RGB_COLORS,(LPVOID)(&lpPixel),NULL,0); //エラーはここ hdcBMP2=CreateCompatibleDC(hdc); hOldBMP2=(HBITMAP)SelectObject(hdcBMP2,hBMP2); ReleaseDC(hwnd,hdc); X=0; Y=1; return 0; case WM_DESTROY: ~中略~ } return DefWindowProc(hwnd,iMsg,wParam,lParam); }

  • かなりかっこ悪いプログラムのような気がします。

    <ソース> #include<stdio.h> int main() { int data[2][3]={{10,20,30}, {1,2,3}}; printf("データ1データ2データ3合計\n"); printf("%5d",data[0][0]); printf("%5d",data[0][1]); printf("%5d",data[0][2]); printf("%5d\n",data[0][0]+data[0][1]+data[0][2]); printf("%5d",data[1][0]); printf("%5d",data[1][1]); printf("%5d",data[1][2]); printf("%5d\n",data[1][0]+data[1][1]+data[1][2]); printf("合計"); printf("%5d",data[0][0]+data[1][0]); printf("%5d",data[0][1]+data[1][1]); printf("%5d",data[0][2]+data[1][2]); return 0; } ただ、printfだけで羅列しているのがかっこ悪いなと思いました。 for文で書こうと思ったのですが、できませんでした。 実行されプログラムはあってます。

  • 読み込んだBMPデータの行方

    参考書を元にBMPを読み込み、 BYTE*型にデータを移して、画像処理や転送に利用できるようにしたいのですが、 どこに画像データの実体が有るのかがよくわかりません・・。 ---------- static LPBYTE lpDIB = NULL; static LPBITMAPINFO lpbiInfo; static LPDWORD lpPixel; LPBYTE lpBMP; LPBITMAPINFOHEADER lpbiBMPInfo; LPBYTE lpBMPPixel; BYTE* ppp; static int iWidth, iHeight, iLength; int iFileSize; DWORD dwOffset; int i, j; HANDLE fhBMP; DWORD dwRead; HDC hdc; PAINTSTRUCT ps; /*BMP取得*/ //ファイルオープン fhBMP = CreateFile("test.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fhBMP == INVALID_HANDLE_VALUE) { MessageBox(NULL, "test.bmpが見つかりません。", "エラー", MB_OK); return 0; } //ファイルサイズ取得 iFileSize = GetFileSize(fhBMP, NULL); //ファイル読み込みバッファ確保 lpBMP = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, iFileSize); //ファイル読み込み ReadFile(fhBMP, lpBMP, iFileSize, &dwRead, NULL); //ファイルを閉じる CloseHandle(fhBMP); //BMP内のBITMAPINFO取得 lpbiBMPInfo = (LPBITMAPINFOHEADER) (lpBMP + sizeof(BITMAPFILEHEADER)); //先頭からピクセル列までのオフセット取得 dwOffset = *(LPDWORD)(lpBMP + 10); //BMP内ピクセル列の先頭アドレス計算 lpBMPPixel = lpBMP + dwOffset; //ビットマップの大きさ取得 iWidth = lpbiBMPInfo->biWidth; iHeight = lpbiBMPInfo->biHeight; //BMPピクセル列の1ラインの長さを計算 if (iWidth % 4 == 0) { iLength = iWidth * 3; } else { iLength = iWidth * 3 + (4 - (iWidth * 3) % 4); } //DIB用バッファを確保 lpDIB = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFO) + iWidth * iHeight * 4); //DIB用ポインタ分配 lpbiInfo = (LPBITMAPINFO)lpDIB; lpPixel = (LPDWORD)(lpDIB + sizeof(BITMAPINFO)); //BITMAPINFO設定 lpbiInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiInfo->bmiHeader.biWidth = iWidth; lpbiInfo->bmiHeader.biHeight = iHeight; lpbiInfo->bmiHeader.biPlanes = 1; lpbiInfo->bmiHeader.biBitCount = 32; lpbiInfo->bmiHeader.biCompression = BI_RGB; //BMP内のピクセル列を32ビット化してコピー for (i = 0;i < iHeight;i++) for (j = 0;j < iWidth; j++) CopyMemory(lpPixel + j + i * iWidth, lpBMPPixel + j * 3 + i * iLength, 3); //ファイル読み込みバッファ解放 HeapFree(GetProcessHeap(), 0, lpBMP); /*描画*/ hdc = BeginPaint(hWnd, &ps); //DIBをウインドウのDCに描画 StretchDIBits(hdc, 0, 0, iWidth, iHeight, 0, 0, iWidth, iHeight, lpPixel, lpbiInfo, DIB_RGB_COLORS,SRCCOPY); EndPaint(hWnd, &ps); ---------- 描画部分のStretchDIBits()を調べて lpPixelに格納されているように思えたのですが、これはただのDWORDですし。 lpBMPPixelだとしても、描画では全く使われていないのが不可解で。 なぜこう(描画にDWORD)なっているのでしょうか? どこに画像データが有るのでしょうか?