0

非常に大きなデータセットをビットマップとして書き込むアプリケーションがあります。[〜500MB]データパッチを上から下に向かって書いています。BMPのファイル構造の性質上、ディスクに書き込まれたらフリップする必要があります。(ビットマップを反転することが一般的なアプリケーションであり、タスクを実行するライブラリを見つけると想定したため、このように記述しました)

インターネットで見つけたコードスニペットを使用して、ビットマップを反転しています。これです:

// GetInvertedBitmap    - Creates a new bitmap with the inverted image
// Returns      - Handle to a new bitmap with inverted image
// hBitmap      - Bitmap to invert
// bLateral     - Flag to indicate whether to invert laterally or vertically

HBITMAP CRisatImport::GetInvertedBitmap( HBITMAP hBitmap, BOOL bLateral )
{
    // Create a memory DC compatible with the display
    CDC sourceDC, destDC;
    sourceDC.CreateCompatibleDC( NULL );
    destDC.CreateCompatibleDC( NULL );
    // Get logical coordinates
    BITMAP bm;
    ::GetObject( hBitmap, sizeof( bm ), &bm );
    // Create a bitmap to hold the result
    HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), 
                        bm.bmWidth, bm.bmHeight);
    // Select bitmaps into the DCs
    HBITMAP hbmOldSource = (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap );
    HBITMAP hbmOldDest = (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult );
    if( bLateral )
        destDC.StretchBlt( 0, 0, bm.bmWidth, bm.bmHeight, &sourceDC, 
                bm.bmWidth-1, 0, -bm.bmWidth, bm.bmHeight, SRCCOPY );
    else
        destDC.StretchBlt( 0, 0, bm.bmWidth, bm.bmHeight, &sourceDC, 
                0, bm.bmHeight-1, bm.bmWidth, -bm.bmHeight, SRCCOPY );
    // Reselect the old bitmaps
    ::SelectObject( sourceDC.m_hDC, hbmOldSource );
    ::SelectObject( destDC.m_hDC, hbmOldDest );
    return hbmResult;
}

問題は、上記のコードについての理解が限られていることです。上記のスニペットをMSDNのサンプルコードから可能な限り使用する関数を作成しようとしました。すべてのリソースを正しくリリースしているとは思いません。そして、私はエラーを理解できないようです-主にGDIについての知識が不足しているためです。誰かが私が間違っていることを指摘してくれたら本当にありがたいです。

この関数を2回呼び出そうとすると、プログラムがクラッシュします。そのため、リソースを誤って解放していると思われます。

これは私が書いた関数です:

void CRisatImport::flipBitMapSaveAsJPG( CString outputFileName, CString outputJPGName, bool saveAsJpg)
{
    // Flip the bitmap to correct odd file structure
        HBITMAP hBitmap;
        hBitmap = (HBITMAP)::LoadImage(NULL, outputFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        hBitmap = GetInvertedBitmap( hBitmap, FALSE );
        CImage image;
        image.Attach(hBitmap);

        image.Save(outputFileName,Gdiplus::ImageFormatBMP);
        if(saveAsJpg){
        image.Save(outputJPGName,Gdiplus::ImageFormatJPEG);
        }

             image.Destroy();

        DeleteObject( hBitmap );
}

このアプリケーションにはMFCとVS2010を使用しています。4GBのRAMがあり、他のアプリケーションは実行されていません。

これは私が得るエラーです:

エラー

4

1 に答える 1

2

ビットマップハンドルをCImageにアタッチすると、ハンドルの存続期間の責任がCImageに渡されるため、後で破棄する必要はありません。ただし、新しいビットマップにも同じ変数名を使用しています。代わりにこれを試してください:

void CRisatImport::flipBitMapSaveAsJPG( CString outputFileName, CString outputJPGName, bool saveAsJpg)
{
    // Flip the bitmap to correct odd file structure
        HBITMAP hBitmapLoad = (HBITMAP)::LoadImage(NULL, outputFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        HBITMAP hBitmapInverted = GetInvertedBitmap( hBitmapLoad , FALSE );
        DeleteObject( hBitmapLoad );

        CImage image;
        image.Attach(hBitmapInverted );

        image.Save(outputFileName,Gdiplus::ImageFormatBMP);
        if(saveAsJpg){
            image.Save(outputJPGName,Gdiplus::ImageFormatJPEG);
        }

        image.Destroy();


}
于 2013-01-24T15:27:29.830 に答える