スクリーンキャプチャしてBMPファイルに保存する方法

このQ&Aのポイント
  • スクリーンキャプチャしてBMPファイルに保存する方法を教えて下さい
  • ダイアログでボタンを押したらスクリーンキャプチャして、それをBMPファイルで保存したいのですがうまく動作しません。
  • ダイアログ画面のサイズは、横 659 画素、縦 486 行です。GetDIBits()で162行まではコピー出来るのですが、それ以上ではエラーを起こします。クリップボードに貼り付ける処理は正常に動作しています。どこがまずいのかを教えていただけたら嬉しいです。よろしくお願い致します。
回答を見る
  • ベストアンサー

スクリーンキャプチャして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; }

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

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

>pInfo->bmiHeader.biWidth=nWid; ピクセル数を設定するので、xsizeにすべきなのかな。

miura-z
質問者

お礼

inthefloiさん ご回答をいただきまして有難う御座いました。 xsizeに変更したところ完全に動作するようになりました。 解決致しました。 大変、有難う御座いました。

関連するQ&A

  • スクリーンキャプチャしてBMP保存する方法を教えてください

    ダイアログでボタンを押すとスクリーンキャプチャしてBMPファイルとして保存したいのですが、うまく動作しません。 どこがまずいのでしょうか?教えていただけると、嬉しいです。 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 nWid3 = (xsize * 3 + 3) & 0xfffffffc; int nBmp = nWid3 * ysize; BYTE *p = new BYTE[nBmp + 54]; SelectObject(hMemDC, hOld); // hMemBmpを非選択とする int lines = GetDIBits(hMemDC, hMemBmp, 0, ysize, (LPBYTE)(p + 54), (LPBITMAPINFO)(p + 14), DIB_RGB_COLORS); // lines -> 0 となり、何もコピーされない。 if(OpenClipboard() != 0){ EmptyClipboard(); SetClipboardData(CF_BITMAP, hMemBmp); // この処理は正常に実行されている CloseClipboard(); } DeleteDC(hMemDC); DeleteDC(hScreenDC); delete [] p; }

  • [MFC] SetTimer関数の扱い方について

    [MFC] SetTimer関数の扱い方について MFCを扱い始めた初心者です。Settimerを用いて1秒間隔でOnTimer関数を呼び出そうと思い試行錯誤していたのですが、どのように記述してよいのかを教えてください。 実装したい機能は、ボタン1によりタイマを開始し、OnTimer関数を1秒間隔で呼び出し、ボタン2によりその動作を停止させたいのです。以下のコードを記述しますので、ご説明をよろしくお願いします。 NForm(){  btnの定義; btn2の定義; Picutureboxのpboxの定義; } int __stdcall WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { Application::Run(new NForm()); return 0; } void NForm::btn_Click(Object *sender, System::EventArgs *e) { if(sender->Equals(btn)){ setTimer(1, 1000, NULL); } else if(sender->Equals(btn2)){ setTimer(1, 1000, NULL); } } void NForm::onTimer(UINT nIDEvent) { if(nIDEvent == 1){ HDC hDC; hDC = GetDC(NULL);//Full screen capture HDC hMemDC = CreateCompatibleDC(hDC); RECT r; SIZE size; size.cx = GetSystemMetrics(SM_CXSCREEN); size.cy = GetSystemMetrics(SM_CYSCREEN); HBITMAP hBitmap = CreateCompatibleBitmap(hDC, size.cx, size.cy); if (hBitmap) { HBITMAP hOld = (HBITMAP) SelectObject(hMemDC, hBitmap); BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOld); DeleteDC(hMemDC); ReleaseDC(NULL, hDC); pbox->Image = Image::FromHbitmap(hBitmap); DeleteObject(hBitmap); } capture_cnt++; char name[80]; sprintf(name, "capture_%d.jpg", capture_cnt); pbox->Image->Save(name,Drawing::Imaging::ImageFormat::Jpeg); NForm::onTimer(1); } else if(nIDEvent == 0){ NForm::onTimer(0); } } 上記のコードにおいて、Ontimer関数を単体で動作させた場合はきちんと動作します。 どうか、よろしくお願いします。

  • BMPの保存

    プリントスクリーンをして、それをBMP形式で保存しようとしているのですが、保存後のファイルを開いてウィンドウを動かすと、それにつれ逐次、画像が更新されていきます。 この問題の原因がわかる方、助言をお願いします。 プログラムはC++で作成しています。 下にソースを載せています。 宜しくお願いします。 #include<windows.h> LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static BITMAPINFO bmpInfo; static LPDWORD lpPixel; static HBITMAP hBitmap; static HDC hMemDC; HWND desktop; RECT rc; static int width,height; switch(uMsg) { case WM_CREATE: //スクリーンの情報を得る desktop=GetDesktopWindow(); GetWindowRect(desktop,&rc); 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); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); return 0; case WM_DESTROY: //自らlpPixelを解放するべからず DeleteDC(hMemDC); DeleteObject(hBitmap); //BMPを削除した時、lpPixelも自動的に解放される PostQuitMessage(0); return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); //表画面へ転送 BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); return 0; } SaveBitmap((HWND)hWnd,"PrintScreen.BMP"); return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) { WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = __FILE__; if(!RegisterClass(&wc)) return 0; HWND hWnd=CreateWindow( __FILE__,"スクリーンキャプチャ", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); if(hWnd==NULL) return 0; BOOL bRet; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1) break; DispatchMessage(&msg); } return (int)msg.wParam; }

  • 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

  • 読み込んだ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)なっているのでしょうか? どこに画像データが有るのでしょうか?

  • OnDraw以外でクライアント領域をBMPに保存できない

    いつもお世話になっています。 MFCでシミュレーション計算プログラムを作っていて クライアント領域の画像をBMPファイルに落とすため 下記サブルーチンを作成しましたが、 ファイルができません。 OnDraw関数に記述すると、 最初の1ステップ目のみファイルが出力されます??? どなたかアドバイス・参考URL等ご教示お願い致します。 また、他に有用なライブラリ等ありましたら、 URL等ご紹介いただければありがたいです。 void CMPSView::SaveBMP(HWND hwnd, char* filename) { DWORD dwSize,dwFSize,dwWidth,dwHeight,dwLength; HANDLE fh; LPBITMAPFILEHEADER lpHead; LPBITMAPINFOHEADER lpInfo; LPBYTE lpBuf,lpPixel; RECT rec; HDC hdc,hdcMem; HBITMAP hBMP,hOld; (中略:バッファ確保、ヘッダ作成) hdc = this->GetDC()->m_hDC; hBMP=CreateCompatibleBitmap(hdc,dwWidth,dwHeight); hdcMem=CreateCompatibleDC(hdc); hOld=(HBITMAP)SelectObject(hdcMem,hBMP); BitBlt(hdcMem,0,0,dwWidth,dwHeight,hdc,0,0,SRCCOPY); SelectObject(hdcMem,hOld); GetDIBits(hdc,hBMP,0,dwHeight,lpPixel,(LPBITMAPINFO)lpInfo,DIB_RGB_COLORS); ReleaseDC(this->GetDC()); DeleteObject(hBMP); DeleteObject(hdcMem); fh=CreateFile(filename, GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); WriteFile(fh,lpBuf,dwFSize,&dwSize,NULL); CloseHandle(fh); GlobalFree(lpBuf); }

  • デバイスコンテキストの宣言に関するエラー?について

    Run-Time Check Failure #3 - The variable 'hMemDC' is being used without being defined. というエラーが出ます。 自分としては、WM_CREATEの処理で、初期化を行っているつもりなのですが・・・ 力を貸して頂ければ有難いです。よろしくお願いします。 ちなみに、関係のありそうな部分だけ掲載しています。 この部分だけ残して、他の部分をコメントアウトしてコンパイルしても、同じエラーメッセージが出ました。 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; RECT rect; HDC hDC; PAINTSTRUCT ps; HDC hMemDC; HBITMAP hMemBmp; HDC hMjDC; HBITMAP hMjBmp; BITMAP MjBmp; /* POINT posMJ; int MJshot; POINT posMJshot;*/ switch (message) { case WM_CREATE: GetClientRect(hWnd, &rect); // クライアント領域の大きさをrectに格納 hDC = GetDC(hWnd); hMemDC = CreateCompatibleDC(hDC); // hDCと互換性をとるメモリデバイスコンテキストhMemDCを構築 hMemBmp = CreateCompatibleBitmap(hMemDC, rect.right, rect.bottom); hMjDC = CreateCompatibleDC(hMemDC); // hMemDCと互換性をとるメモリデバイスコンテキストhMjDCを構築 hMjBmp = (HBITMAP)LoadImage( // ビットマップイメージMYJET(リソース)をhMjBmpに設定 (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_MYJET), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR ); SetTimer(hWnd, 1, 10, NULL); // 100分の1秒毎にWM_TIMERメッセージを送るタイマー1をセット break; case WM_PAINT: hDC = BeginPaint(hWnd, &ps); // hDCにディスプレイのデバイスコンテキストのハンドルを格納 BitBlt( // hDCにバックバッファhMemDCを転送 hDC, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY ); EndPaint(hWnd, &ps); break;

  • ビットマップの編集について

    どなたかビットマップ編集の経験のある方で分かる方おられましたらアドバイス頂きたいと思い書かせていただきます。 デバイスコンテキストからビットマップを作成したいのですが、作成結果が真っ黒なビットマップになります。多分ビットマップ情報がメモリDCに描画できていないまま作成しているという事なのでしょうか? MemDC = CreateCompatibleDC(元DC); ↓ hBitmap = CreateCompatibleBitmap(元DC,Width,LlnHeight); ↓ SelectObject(MemDC ,hBitmap) ↓ GetObject(MemDC ,tpBitmap,(LPSTR)&tpBitmap); ↓ Liret = GetDIBits(元DC, hBitmap, 0, (WORD)tpBmpIH.biHeight,NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); ↓ Liret = GetDIBits(元DC, hBitmap, 0, (WORD)tpBmpIH.biHeight,(LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); 関係ありそうな所ははこんな感じで操作してます。 Bitbltがサポートされていない様なので別の方法でメモリDCに転送させなければいけないのでしょうか?

  • メモリデバイスコンテキスト&ビットマップハンドル

    static VOID _SetSize(pLayer object, LONG w, LONG h) { LayerEx * obj; obj = (LayerEx *)object; obj->size.x = w; obj->size.y = h; if(obj->hBitmap){ HDC hdc , hNewDC; HBITMAP hNewBitmap; hdc = object->GetDC(object); hNewDC = CreateCompatibleDC(hdc); hNewBitmap = CreateCompatibleBitmap(hdc , w , h); SelectObject(hNewDC , hNewBitmap); BitBlt(hNewDC , 0 , 0 , w , h , hdc , 0 , 0 , SRCCOPY); DeleteObject(hNewDC); object->DeleteDC(object , hdc); DeleteObject(obj->hBitmap); obj->hBitmap = hNewBitmap; } 一度生成したビットマップのサイズを変更してもう一度ビットマップを生成するプログラムらしいのですが、 BitBlt(hNewDC , 0 , 0 , w , h , hdc , 0 , 0 , SRCCOPY); ↑なぜBitBltで転送しているのかわかりません。 新しく生成したビットマップをSelectObjectで登録したらいいような感じがするんですが・・・ DeleteObject(hNewDC); ↑あとこれはDeleteDC(hNewDC)の間違いなのでしょうか?ここも何しているか分かりません。 分かる人いたら教えてください。説明足りなかったらごめんなさい^^; ↓一応object->GetDC(object)のソースです。 static HDC _GetDC(pLayer layer) { LayerEx * obj; HDC hResult; obj = (LayerEx *)layer; if(obj->hBitmap == NULL){ HDC hdc; hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); obj->hBitmap = CreateCompatibleBitmap(hdc, obj->size.x, obj->size.y); hResult = CreateCompatibleDC(hdc); SelectObject(hResult, obj->hBitmap); DeleteDC(hdc); } else{ hResult = CreateCompatibleDC(NULL); SelectObject(hResult, obj->hBitmap); } return hResult; }

専門家に質問してみよう