C++HBITMAP 를 비트 맵 파일 로 저장 하 는 방법

본 고 는 C++를 사용 하여 비트 맵 핸들 HBITMAP 를 비트 맵 파일 로 저장 하고 C++캡 처 코드 와 결합 하면 캡 처 파일(.bmp)을 저장 할 수 있 습 니 다.
그 절 차 는 다음 과 같다.
1.비트 맵 파일 만 들 기;
2.비트 맵 에서 모든 픽 셀 이 차지 하 는 바이트 수 를 계산 합 니 다.
3.비트 맵 구조 BITMAP 가 져 오기;
4.구조 비트 맵 정보 헤드 BITMAPInfoheader;
5.비트 맵 파일 헤더 BITM APFILEHEADER 를 구성 합 니 다.
6.비트 맵 내용 에 메모 리 를 분배 합 니 다.
7.팔레트 처리 하기;
8.파일 쓰기;
9.자원 을 삭제 합 니 다.
다음은 C++소스 코드:
ImageHelper.h

#pragma once
 
#include <windows.h>
#include <string>
using namespace std;
 
class ImageHelper
{
public:
    static bool SaveBitmapToFile(HBITMAP bitmap, const string& filename); //       
 
private:
    static WORD GetBitmapBitCount(); //               
    static void ProcessPalette(HBITMAP hBitmap, const BITMAP& bitmap,
        DWORD paletteSize, LPBITMAPINFOHEADER lpBmpInfoHeader); //     
};
ImageHelper.cpp

#include "ImageHelper.h"
#include <shlwapi.h>
 
 
bool ImageHelper::SaveBitmapToFile(HBITMAP hBitmap, const string& filename)
{
    //1.       
    const auto file = CreateFileA(filename.c_str(), GENERIC_WRITE,
        0, nullptr, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
        nullptr);
    if (file == INVALID_HANDLE_VALUE)
    {
        return false;
    }
 
    //2.                
    const auto bitCount = GetBitmapBitCount();
 
    //3.       
    BITMAP bitmap;
    ::GetObject(hBitmap, sizeof(bitmap), reinterpret_cast<LPSTR>(&bitmap));
 
    //         (32    )
    const DWORD bmBitsSize = ((bitmap.bmWidth * bitCount + 31) / 32) * 4 * bitmap.bmHeight;
 
    //     
    const DWORD paletteSize = 0;
 
    //4.        
    BITMAPINFOHEADER  bmpInfoHeader; //       
    bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfoHeader.biWidth = bitmap.bmWidth;
    bmpInfoHeader.biHeight = bitmap.bmHeight;
    bmpInfoHeader.biPlanes = 1;
    bmpInfoHeader.biBitCount = bitCount;
    bmpInfoHeader.biCompression = BI_RGB;
    bmpInfoHeader.biSizeImage = 0;
    bmpInfoHeader.biXPelsPerMeter = 0;
    bmpInfoHeader.biYPelsPerMeter = 0;
    bmpInfoHeader.biClrImportant = 0;
    bmpInfoHeader.biClrUsed = 0;
 
    //5.        
    BITMAPFILEHEADER bmpFileHeader;
    bmpFileHeader.bfType = 0x4D42; //"BM"
    //      
    const DWORD dibSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paletteSize + bmBitsSize;
    bmpFileHeader.bfSize = dibSize;
    bmpFileHeader.bfReserved1 = 0;
    bmpFileHeader.bfReserved2 = 0;
    bmpFileHeader.bfOffBits = static_cast<DWORD>(sizeof(BITMAPFILEHEADER))
        + static_cast<DWORD>(sizeof(BITMAPINFOHEADER)) + paletteSize;
 
    //6.           
    const auto dib = GlobalAlloc(GHND, bmBitsSize + paletteSize + sizeof(BITMAPINFOHEADER)); //    
    const auto lpBmpInfoHeader = static_cast<LPBITMAPINFOHEADER>(GlobalLock(dib)); //         
    *lpBmpInfoHeader = bmpInfoHeader;
 
    //7.      
    ProcessPalette(hBitmap, bitmap, paletteSize, lpBmpInfoHeader);
 
    //8.     
    DWORD written = 0; //          
    WriteFile(file, reinterpret_cast<LPSTR>(&bmpFileHeader), sizeof(BITMAPFILEHEADER),
        &written, nullptr); //       
    WriteFile(file, reinterpret_cast<LPSTR>(lpBmpInfoHeader), dibSize,
        &written, nullptr); //          
 
    //9.     
    GlobalUnlock(dib);
    GlobalFree(dib);
    CloseHandle(file);
 
    return true;
}
 
//               
WORD ImageHelper::GetBitmapBitCount()
{
    const auto dc = ::CreateDCA("DISPLAY", nullptr, nullptr, nullptr);
    //              
    const auto bits = ::GetDeviceCaps(dc, BITSPIXEL) * GetDeviceCaps(dc, PLANES);
    ::DeleteDC(dc);
 
    //           
    WORD bitCount;
    if (bits <= 1)
        bitCount = 1;
    else if (bits <= 4)
        bitCount = 4;
    else if (bits <= 8)
        bitCount = 8;
    else
        bitCount = 24;
 
    return bitCount;
}
 
//     
void ImageHelper::ProcessPalette(HBITMAP hBitmap, const BITMAP& bitmap,
    DWORD paletteSize, LPBITMAPINFOHEADER lpBmpInfoHeader)
{
    HANDLE oldPalette = nullptr;
    HDC dc = nullptr;
    const auto palette = GetStockObject(DEFAULT_PALETTE);
    if (palette != nullptr)
    {
        dc = ::GetDC(nullptr);
        oldPalette = ::SelectPalette(dc, static_cast<HPALETTE>(palette), FALSE);
        ::RealizePalette(dc); //       
    }
 
    //            
    GetDIBits(dc, hBitmap, 0, static_cast<UINT>(bitmap.bmHeight),
        reinterpret_cast<LPSTR>(lpBmpInfoHeader) + sizeof(BITMAPINFOHEADER) + paletteSize,
        reinterpret_cast<BITMAPINFO*>(lpBmpInfoHeader), DIB_RGB_COLORS);
 
    //     
    if (oldPalette != nullptr)
    {
        ::SelectPalette(dc, static_cast<HPALETTE>(oldPalette), TRUE);
        ::RealizePalette(dc);
        ::ReleaseDC(nullptr, dc);
    }
}
이상 은 C++HBITMAP 를 비트 맵 파일 로 저장 하 는 실현 방법 에 대한 상세 한 내용 입 니 다.C++HBITMAP 저장 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기