ビットマップ編集の経験がある方へのアドバイスをお願いします

このQ&Aのポイント
  • ビットマップの作成結果が真っ黒な状態になってしまいます。おそらく、ビットマップ情報がメモリDCに描画されていないまま作成されているのが原因ではないかと思います。
  • 現在の操作ではBitbltがサポートされていないため、別の方法でメモリDCに転送する必要があるかもしれません。
  • ビットマップ編集に経験のある方で、この問題の解決方法をご存知の方がいらっしゃいましたら、アドバイスをいただければと思います。
回答を見る
  • ベストアンサー

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

どなたかビットマップ編集の経験のある方で分かる方おられましたらアドバイス頂きたいと思い書かせていただきます。 デバイスコンテキストからビットマップを作成したいのですが、作成結果が真っ黒なビットマップになります。多分ビットマップ情報がメモリ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に転送させなければいけないのでしょうか?

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

  • ベストアンサー
  • tettsu
  • ベストアンサー率30% (4/13)
回答No.4

見たところ、おかしな点は無いような気がしますが・・・ 以下は、私の使っているHDCの内容をBMPに出力する関数です。 bool SaveWindowImageForBMP(HDC hDC, int width, int height, const char *file_name) { if (file_name == NULL){ return false; } DWORD dwSize, dwFSize, dwWidth, dwHeight, dwLength; HANDLE fh; LPBITMAPFILEHEADER lpHead; LPBITMAPINFOHEADER lpInfo; LPBYTE lpBuf,lpPixel; HDC hdcMem; HBITMAP hBMP,hOld; dwWidth=width; dwHeight=height; if ((dwWidth*2) % 4==0){ // バッファの1ラインの長さを計算 dwLength=dwWidth*2; } else { dwLength=dwWidth*2+(4-(dwWidth*2) % 4); } // 書き込み用バッファのサイズ計算 dwFSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwLength*dwHeight; // バッファ確保とポインタ設定 lpBuf=(LPBYTE)GlobalAlloc(GPTR,dwFSize); lpHead=(LPBITMAPFILEHEADER)lpBuf; lpInfo=(LPBITMAPINFOHEADER)(lpBuf+sizeof(BITMAPFILEHEADER)); lpPixel=lpBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); // 16ビットBMPファイルのヘッダ作成 lpHead->bfType='M'*256+'B'; lpHead->bfSize=dwFSize; lpHead->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); lpInfo->biSize=sizeof(BITMAPINFOHEADER); lpInfo->biWidth=dwWidth; lpInfo->biHeight=dwHeight; lpInfo->biPlanes=1; lpInfo->biBitCount=16; // ウインドウのデバイスコンテキスト互換のBITMAP作成 hBMP=CreateCompatibleBitmap(hDC,dwWidth,dwHeight); // BITMAPにウインドウのクライアント領域をコピー 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); ::DeleteObject(hBMP); ::DeleteObject(hdcMem); // バッファをファイルに書き出す fh=CreateFile(file_name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(fh == INVALID_HANDLE_VALUE){ GlobalFree(lpBuf); //確保したメモリの開放 return false; } if (WriteFile(fh,lpBuf,dwFSize,&dwSize,NULL) == 0){ CloseHandle(fh); GlobalFree(lpBuf); //確保したメモリの開放 return false; } CloseHandle(fh); GlobalFree(lpBuf); //確保したメモリの開放 return true; }

Toyochan8
質問者

お礼

引き続き回答有難うございます。 自分でもなぜモノクロ以外だと正常に描画できないのか、プリンタDCからだと描画が正常にできないのか分かりません・・。 自分はVC++ Ver1.51を使用しているのでtettsuさんに書いていただいたソースコードと大きく変わるところといえば WriteFile関数の所なのかなと自分では思っています。 私のコードだと、ファイルに書き込むとき以下のようにループさせなければいけないので、szBufferの確保が正常に出来ていないのかとも考えたりしています。 _lwriteだと一度で書き込むことが出来ないみたいなので・・。 lCount = (long)LtpBitmapFH.bfSize - sizeof (BITMAPFILEHEADER); lBuffCnt = 0; while(1) {   if (lCount<=lBuffCnt) break;   Liret = _lwrite( hF,&szBuffer[lBuffCnt], 1);   lBuffCnt = lBuffCnt + 1; } ここまで書いて頂いたのに自分で解消できず申しわけ有りません。 自分でももう少し進展するまで締め切るのを待とうと思います。 もし後ほどお気づきになるようなことがありましたら又アドバイスいただけると幸いです。

Toyochan8
質問者

補足

アクティブウインドウからのビットマップ作成に成功しました。 ビットマップのサイズを小さくして作成してみた所、カラーでも正常に作成できたので、LlnSelObj が 65534 を超えてしまった場合に正常に出ないような気がしてヒュージに変えてみた所、正常に出力されました。 有り難うございました。 char _huge *a; a = (char *)GlobalLock(hDIB); LlnSelObj = (long)LtpBitmapFH.bfSize - sizeof (BITMAPFILEHEADER); LlnBuffCnt = 0; while(1) { if (LlnSelObj<=LlnBuffCnt) break; Liret = _lwrite( hF,a, 40); a = a + 40; LlnBuffCnt+=40; }

その他の回答 (3)

  • tettsu
  • ベストアンサー率30% (4/13)
回答No.3

> 結果BitBltは使ってテストでアクティブウインドウを元DCにして試してみたのですが、完成時のビットマップが横方向に帯状に同じ画像が出力されていました。 画像は、どのようにして確認されたのでしょうか? 多分、ビットマップの仕様で、横幅のバイト数が4の倍数になるというのがあてはまりそうな気がします。 たとえば、10×10の24ビットカラーのビットマップの場合に、取得できるビットイメージは、 横32バイト(3バイト×10で30バイト。4の倍数にするため2を足す) 縦30バイト 合計960バイト必要になります。 > 元DCをプリンタのDCにした場合、なぜか真っ黒なビットマップになってしまいました。元DCをプリンタのDCに変えた場合とデスクトップのアクティブウインドウにした場合で何か違いが有ったのでしょうか? DC(デバイスコンテキスト)は、出力デバイスを仮想化したものです。(間違ってるかも知れませんが、私はこう理解してます。) ディスプレイに表示されているウインドウの場合は、表示されているままのビットイメージが取れます。 もし、この対象のウインドウに他のウインドウが上に重なっている場合は、対象ウインドウに重なった状態で取得されてしまいます。 プリンタのDCの場合、やったこと無いですが、他のアプリケーション等で印刷を指示して、実際に出力が始まるまでの間になら、ビットイメージが取得できる可能性があるかもしれないです。でも、もちろんハードウェアに依存すると思います。

Toyochan8
質問者

補足

アドバイス有り難うございます。 >画像は、どのようにして確認されたのでしょうか? BITMAPFILEHEADER→BITMAPINFOHEADER→ビットマップ情報と順に新規作成ファイルに書き込んでいきました。出来たBMPファイルをペイントツールで開いて確認しました。 BITMAPFILEHEADER は以下になります。 bfType = 19778(BM) bfSize = 358454 bfReserved1、bfReserved2 = 0 bfOffBits= 54 BITMAPINFOHEADER は以下になります。 biSize = 40 biWidth = 560 biHeight = 320 biPlanes = 1 biBitCount = 16 biCompression = 0 biSizeImage = 358400 その他項目は 0 です。 BITMAPFILEHEADER を書き込んだ後、 char *szBuffer; hHndl = GlobalReAlloc(LhDIB,LdwLen,GMEM_MOVEABLE); // LdwLen = 358440 です。 LhDIB = hHndl; lpbi = (LPBITMAPINFOHEADER)GlobalLock(LhDIB); Liret = GetDIBits(MhBitmapMemDC, MhBitmapDC, 0, (WORD)LtpBmpIH.biHeight,(LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); szBuffer = (char *)GlobalLock(LhDIB); lCount = (long)LtpBitmapFH.bfSize - sizeof (BITMAPFILEHEADER); lBuffCnt = 0; while(1) { if (lCount<=lBuffCnt) break; Liret = _lwrite( hF,&szBuffer[lBuffCnt], 1); lBuffCnt = lBuffCnt + 1; } で書き込んでファイルを作成しました。

  • guccii
  • ベストアンサー率31% (14/44)
回答No.2

以前GetDeviceCapsの使用を回答したものです。 うる憶えで答えてしまって、逆に時間をとらせてしまったみたいです。大変申し訳ありませんでした。

Toyochan8
質問者

お礼

gucciiさん、お気になさらないで下さい。 gucciiさんに頂いたアドバイスはビットマップ編集初めての自分にとって充分に参考になりました。これからももし困って質問書き込むようなことがあれば又、アドバイスなどして頂ければ嬉しく思います。

  • tettsu
  • ベストアンサー率30% (4/13)
回答No.1

元DCの画像からビットマップを作成したいのでしょうか? であれば、通常なら MemDC = CreateCompatibleDC(元DC); //元DCと互換のメモリDC生成 hBitmap = CreateCompatibleBitmap(元DC,Width,LlnHeight);//元DCと互換のあるビットマップ生成 SelectObject(MemDC ,hBitmap);//メモリDCにビットマップを関連付け。この時点ではビットマップは空 このあとに、 Bitbltで、元DCから、MemDCへビットを転送するのですが、 Bitbltがサポートされていないデバイスコンテキストからだと、 GetPixelを使って、元DCから1ピクセルずつ取得して、 MemDCへSetPixelを使って書き込むことになると思います。 その後、GetDIBitsにMemDCと、hBitmapを渡せば、ビット情報が取得できると思います。 ですが、Bitbltをサポートしてないとなると、GetDIBitsもサポートしてない可能性もありますよね。 なので、最初のCreateCompatibleDCに渡すDCはデスクトップウインドウのDCが良いかもしれないです。 ちょっと後学の為に教えていただきたいのですが、Bitbltをサポートしてないデバイスコンテキストというと、プロッタ等のプリンタしか思い浮かばないのですが、元DCのハードウェアって何ですか?

Toyochan8
質問者

お礼

丁寧にアドバイス頂き、有難うございます。 BitBltがサポートされていないと思ったのは自分の勘違いでGetDeviceCapsの引数に直接 RC_BITBLT を渡していたためにサポートされていないと思い込んでいたためでした、申しわけ有りません。 結果BitBltは使ってテストでアクティブウインドウを元DCにして試してみたのですが、完成時のビットマップが横方向に帯状に同じ画像が出力されていました。 下の図を1枚のビットマップ画像とすると 0123456789012 ←1本目の帯状画像 3456789012345 ←2本目の帯状画像 7890123456789 ←3本目の帯状画像 5678901234567 ←4本目の帯状画像 といったようにそれぞれの帯でずれた状態で帯状に描画されていました。 ヘッダ情報のbiBitCountを1に変更してモノクロ画像にすると若干ずれが有ったような気もしましたが一応ウインドウの画像がモノクロで描画できました。また、元DCをプリンタのDCにした場合、なぜか真っ黒なビットマップになってしまいました。元DCをプリンタのDCに変えた場合とデスクトップのアクティブウインドウにした場合で何か違いが有ったのでしょうか?

関連するQ&A

  • 画像操作について2

    どなたか助けてください。 下記ソースをチェックしていただけないでしょうか? ビットマップ画像処理を行うために、CreateDIBSection()で編集領域を 確保して、imageにコピーして画像操作を行いたいのですが、 Debug Assertion Failedというエラーがでます。 知識不足ということもあり、ソース自体に問題がある可能性の方が高いのですが、 根本的に画像操作に対する考え方が間違っているのでしょうか? ご教授よろしくお願い致します。 環境はVC++6.0 MFC ダイアログベースです BOOL C***Dlg::*******() { HBITMAP hBmp; BITMAPINFOHEADER bi; unsigned *bmbuf; image , MemDC, MemDC2はPublicです。 bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = 16; bi.biHeight = -40; //top-down bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; hBmp=CreateDIBSection(NULL, (LPBITMAPINFO)&bi, DIB_RGB_COLORS, (void **)(&bmbuf), NULL, 0); CDC* pDC = this->GetDC(); MemDC.CreateCompatibleDC(pDC); SelectObject(MemDC.m_hDC,hBmp); MemDC2.CreateCompatibleDC(pDC); HBITMAP h_BMP = (HBITMAP)LoadImage(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_******), IMAGE_BITMAP, 16, 40, LR_CREATEDIBSECTION); HBITMAP h_OLD_BMP = (HBITMAP)::SelectObject(MemDC2.m_hDC,h_BMP); m_pbg1dc->BitBlt(42,16,100,100,&MemDC2,0,0,SRCCOPY); memcpy(image, bmbuf, 16 * 40 * 4); ::SelectObject(MemDC2.m_hDC,h_OLD_BMP); MemDC2.DeleteDC(); DeleteObject(hBmp); return TRUE; }

  • ビットマップのコピーについて

    はじめまして。 ビットマップ操作について勉強をしております。 現在、ビットマップファイルを読み込んでメモリDC上でコピーし、新しいファイルを生成するプログラムを作っております。 手順としては 1. LoadImageでBMPファイルを読み込み、ハンドルを取得。 hdcmem_old = CreateCompatibleDC ( NULL ); SelectObject( hdcmem_old , hBitmap_old ); 2. hdcmem_new = CreateCompatibleDC ( NULL ); hBitmap_new = CreateDIBSection( hdcmem_new , (BITMAPINFO*)&bmpInfoHeader , DIB_PAL_COLORS , (void **) &Pixel , NULL , 0 ); SelectObject( hdcmem_new, hBitmap_new ); 3. BitBlt( hdcmem_new , 0 , 0 , LCD_WIDTH , LCD_HEIGHT , hdcmem_old , 0 , 0 , SRCCOPY ) でデータを転送後、ビットマップファイルのヘッダを取り出し、&Pixelからビットデータを加えて新たなファイルを生成しているのですが、生成された画像を見ると全黒になっております。 メモリDCを完全に理解してないせいか、解決策がみあたりません。 もしよろしければ、解決策、またはヒントをご教授していただければと思います。 よろしくお願いします。

  • GetDIBits関数の使い方について

    いつも丁寧なご回答を頂きありがとうございます。 GetDIBits関数の使い方について質問させて頂きます。 http://msdn.microsoft.com/ja-jp/library/cc428673.aspx 上記サイトを参考にして色々と試してみてWin32APIでは正常に動作したのですが、C#で正常に動作しません。 <Win32API> LPCOLORREF pScanData = NULL; BITMAPINFOHEADER bmpinfo = {0}; pScanData = new COLORREF[ bmp.bmWidth ]; bmpinfo.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.biWidth = bmp.bmWidth; bmpinfo.biHeight = bmp.bmHeight; bmpinfo.biPlanes = 1; bmpinfo.biBitCount = 32; bmpinfo.biCompression = BI_RGB; // 一行分画像データを DIB で取り出す GetDIBits( hdc, hBitmap,1, 1, pScanData, (LPBITMAPINFO)&bmpinfo, DIB_RGB_COLORS ); 特に第5、6引数に何を渡してやればいいのかがわかりません。 以上ご助言よろしくお願いいたします。

  • OnPaint() とOnDraw()の違いについて

    OnPaint内に記述した下記コードでビットマップが描画されますが、OnDraw内だと描画されません。 どうしてなのか教えてください。 お願いします。 void CAbcView::OnPaint() { HBITMAP myDIB; // ビットマップのハンドル HBITMAP oldDIB; HDC hDC; // デバイスコンテキストのハンドル HDC hCompatiDC; // メモリデバイスコンテキスト PAINTSTRUCT ps; // クライアント領域の描画に使う情報を保持 if(!m_BmpInfo) return; hDC = ::GetDC(m_hWnd);//これでもOK ::BeginPaint(m_hWnd,&ps); hCompatiDC = ::CreateCompatibleDC(hDC);//hDC); myDIB = ::CreateDIBitmap(hDC,&m_BmpInfo->bmiHeader, CBM_INIT,m_BmpImage,m_BmpInfo,DIB_RGB_COLORS); oldDIB=(HBITMAP)::SelectObject(hCompatiDC,myDIB); BitBlt(hDC,5,25,m_BmpInfo->bmiHeader.biWidth, m_BmpInfo->bmiHeader.biHeight,hCompatiDC,0,0,SRCCOPY); 略 } 環境 WIN98 VC++6.0 MFC にて

  • ビットマップを表示させる(MFC)

    CDC::SelectObject を使用して、 ビットマップをメモリDCに割り当てたあと、 CDC::BitBltで画面に表示しています。 すでに、画面に表示されているビットマップを残したまま、 2枚目のビットマップを表示したいのですが、 2枚目を表示すると同時に1枚目のビットマップが消えてしまいます。 (当然ですが。。。) 1枚目(すでに表示させているビットマップ)を残し、 2枚目のビットマップを同じ画面に表示するには、 どうすればよいでしょうか?

  • ワードのファイルをビットマップで読み出すには

     ワードの画面にビットマップ(絵や写真)を貼り付けることは出来ますが、逆にビットマップの画面に、ワードで保存してあるファイルを呼び出そうとすると、「このファイルは読み取れません」と言うエラーメッセージが出て、呼び出せません  仕方がないので、ワードで作成した書類は、印刷して、スキャナーで読み取りビットマップに取り込んでいます。 その他に方法がありましたら教えて下さい。

  • ビットマップ画像の表示

    どうしても正確に動作をしないので、問題点をご指摘していただきたいです。 開発環境はVisual Studio 2005です 24bitのビットマップ画像を読み込み、新しいwindowを作成して表示するプログラムを作成しています。 しかし、読み込んでから新しいWindowは作成されるのですが、どうしても画像が表示されません。 私が気にしている部分は、画像を読み込んでから新しく作成するWindowのプロシージャにおいて、WM_PAINTメッセージで行うべき処理です。 以下にプロシージャを載せます。 LRESULT CALLBACK WndProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam ){ PAINTSTRUCT ps; switch( Message ){ case WM_PAINT: BeginPaint( hWnd, &ps ); SetDIBitsToDevice( ps.hdc, 0, 0, pDib->biWidth, pDib->biHeight, 0, 0, 0, pDib->biHeight, pBitmap, (BITMAPINFO *)pDib, DIB_RGB_COLORS ); EndPaint( hWnd, &ps ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, Message, wParam, lParam ); } return 0; } pDibは PBITMAPINFOHEADER のグローバル変数です。 そしてpDibへ情報を格納するとき、 bitmapSize = bmFileHdr.bfSize - sizeof(BITMAPFILEHEADER);   pDib = ( BITMAPINFOHEADER * )malloc( bitmapSize ); と領域を確保し、   fread( pDib, bitmapSize, 1, fp ) というように格納しました。 このときの fp は BITMAPFILEHEADER の分だけ進んでいます。 bmFileHdr は BITMAPFILEHEADERです。 つまりBITMAPFILEHEADER以降の情報を全て格納しました。 また SetDIBitsToDevice での題10引数の pBitmap は    pBitmap = (BYTE *)(pDib) + bmFileHdr.bfOffBits - sizeof(BITMAPFILEHEADER); のように求めました。先ほども記述しましたが pDib には BITMAPFILEHEADER 以降の情報を全て格納したので、pDibからヘッダ部分のみポインタを進めました。 やはり WM_PAINTメッセージの部分で、SetDIBitsToDevice関数だけではなく、そのほかに設定することがあるのでしょうか?

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

  • Windowsプログラミング 画面描画 ちらつき

    SetDIBitsToDevice関数を使って画面に描画をした後、LineTo関数やEllipse関数を使って その画面上に線や丸を表示させる処理をしているのですが、描画処理を一度にできていないためか ちらつきが発生してしまいます。 調べてみるとビットマップのマルチバッファリングなどが解決策にあるのですが、 私は一次元配列で画素値を格納していてビットマップに情報は保持していないため よく解決策で使われているBITBLTが使えない状態です。 裏画面に描画しておいて、最終的に描画は一度だけにするという考えは分かるんですが、 これをSetDIBitsToDevice関数を用いてちらつきが発生しないようにできるんでしょうか? プログラムとしては画像の上に線と円をひたすら描画していくようなイメージをしています。 アドバイスお願いします! case WM_PAINT: hDC=BeginPaint(hParent,&ps); SetDIBitsToDevice( ps.hdc, 0, 0,// コピー先x,y座標 pimg -> bih.biWidth,// DIBの幅 pimg -> bih.biHeight,// DIBの高さ 0, 0,// DIBの座標 0,// 走査線 pimg -> bih.biHeight,/ 走査線数 pimg -> lpBmpData, (BITMAPINFO *)&( pimg -> bih),// BITMAPINFOにキャスト DIB_RGB_COLORS ); for(int i=0; i<number-1; i++){ if(i==0){  hPen1 = CreatePen(PS_SOLID, 1, RGB(255,0,0));  electObject(hDC,hPen1);  MoveToEx(hDC,Xs,Ys,NULL);  Ellipse(hDC,Xs-2,Ys-2,Xs+2,Ys+2); }else{  LineTo(hDC,Xe,Ye);  Ellipse(hDC,Xs-2,Ys-2,Xs+2,Ys+2); } }

  • 画像ファイルの編集の方法

    画像にはいろんなフォーマットがありますが、ソフトウェアを使うとフォーマット変換ができます。そこで例えばビットマップに変換できたとします(変換には不可逆とか不可逆の圧縮とかありますが、そこはとりあえず不問で)。 そこでプログラムによってビットマップを何らかの方法で数値として取り出し、編集してまた元に戻すことを考えています。これが自在にできると大きな自由度を得ることができます。ビットマップですから平面に展開された数値(RGB値?)だと思います。編集作業が一番難しいのでしょうが、プログラムを駆使して何かができてそれを元に戻すと編集後の画像が再構成されます。このようなことを実行する方法はC++とかJAVAなのかなと思うのですが、実際どのようにして行うことが可能でしょうか。そのようなテンプレートのようなプログラムがあると助かるのですが。画像ファイルのヘッダーなどは形式によって決まっているのではないかと思いますが。なお、できるのであれば形式はビットマップでなくてもいいです。よろしくお願いします。

専門家に質問してみよう