翻转位图后正确释放资源

时间:2013-01-24 06:58:26

标签: visual-studio-2010 visual-c++ mfc

我有一个将非常大的数据集写为位图的应用程序。 [~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缺乏了解。如果有人指出我做错了什么,我真的很感激。

如果我尝试两次调用此函数,程序会崩溃 - 这就是为什么我怀疑我正在错误地释放资源。

这是我写的函数:

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,没有其他应用程序正在运行。

这是我得到的错误:

Error http://s7.postimage.org/97xswxd23/Capture.jpg

1 个答案:

答案 0 :(得分:2)

当您将位图句柄附加到CImage时,您将把句柄的生命周期的责任移交给CImage,因此您不希望在之后使用Destory。但是你也为新的位图使用相同的变量名。试试这个:

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();


}