StretchBlt 函数返回一个奇怪的白点位图

问题描述 投票:0回答:1

我正在尝试使用窗口 API 编写一个简单的位图缩放器应用程序,这是我的位图缩放器函数:

BOOL ResizeBitmap(HBITMAP hOriginalBitmap, const char resizedFilename[], BitmapAngle NewAngle, BitmapAngle BmAngle){
    HDC hdcSrc = CreateCompatibleDC(NULL);
    HGDIOBJ originalObject = SelectObject(hdcSrc, hOriginalBitmap);

    HDC hdcDest = CreateCompatibleDC(NULL);
    HBITMAP hNewBitmap = CreateCompatibleBitmap(hdcDest, NewAngle.Width, NewAngle.Height);

    if (!hNewBitmap) {
        GetErrorCode("CreateCompatibleBitmap");
        ExitProcess(0);
    }

    SelectObject(hdcDest, hNewBitmap);

    // Set the stretch mode to HALFTONE for better quality
    SetStretchBltMode(hdcDest, HALFTONE);
    SetBrushOrgEx(hdcDest, 0, 0, NULL);

    // Use StretchBlt to resize the original bitmap onto the new bitmap
    StretchBlt(hdcDest, 0, 0, NewAngle.Width, NewAngle.Height,
               hdcSrc, 0, 0, BmAngle.Width, BmAngle.Height,
               SRCCOPY);

    // BitBlt(hdcDest, 0, 0, NewAngle.Width, NewAngle.Height, hdcSrc, 0, 0, SRCCOPY);
    // Save the resized bitmap to a file
    SaveBitmapToFile(hNewBitmap, NewAngle, resizedFilename);

    SelectObject(hdcSrc, originalObject);
    DeleteDC(hdcSrc);
    DeleteDC(hdcDest);
    DeleteObject(hNewBitmap);

    return TRUE;
}

这是我的 SaveBitmapToFile 函数:

BOOL SaveBitmapToFile(HBITMAP hBitMap, BitmapAngle Angle, const char NewFileName[]) {
    HDC hDevice = CreateCompatibleDC(NULL);
    SelectObject(hDevice, hBitMap);

    BITMAPINFOHEADER BitmapInfoHeader = GetBitmapInfoHeader(Angle);
    BITMAPFILEHEADER BitMapFileHeader = GetBitmapFileHeader(Angle);

    DWORD AllocatedSize = Angle.Width * Angle.Height * 3;  // Assuming 24 bits per pixel

    BYTE* BitmapData = VirtualAlloc(NULL, AllocatedSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    int Result = GetDIBits(hDevice, hBitMap, 0, Angle.Height, BitmapData, (BITMAPINFO*)&BitmapInfoHeader, DIB_RGB_COLORS);

    if (!Result) {
        GetErrorCode("GetDIBits");
        ExitProcess(0);
    }

    HANDLE hFile = CreateFileA(NewFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (!hFile) {
        GetErrorCode("CreateFileA");
        ExitProcess(0);
    }

    // Write headers and bitmap data to the file
    WriteFile(hFile, &BitMapFileHeader, sizeof(BITMAPFILEHEADER), NULL, NULL);
    WriteFile(hFile, &BitmapInfoHeader, sizeof(BITMAPINFOHEADER), NULL, NULL);
    WriteFile(hFile, BitmapData, AllocatedSize, NULL, NULL);

    CloseHandle(hFile);

    VirtualFree(BitmapData, AllocatedSize, MEM_RELEASE);

    DeleteDC(hDevice);

    if (!GetLastError()) {
        return TRUE;
    } else {
        GetErrorCode("SaveBitmapToFile");
        return FALSE;
    }
}

但是,结果位图文件看起来很奇怪,它只是一个带有白点的位图:

The input bitmap The Output bitmap

当我尝试截图时,SaveBitmapToFile 函数工作得非常好,所以我认为问题出在 ResizeBitmap 函数中

这是我的截图功能,效果非常好。

HBITMAP GetScreenBitmap() {
    HDC hdcScreen = GetDC(NULL);
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    // Create a compatible memory DC using the screen DC
    HDC hdcMem = CreateCompatibleDC(hdcScreen);

    // Create a compatible bitmap using the screen DC
    HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, screenWidth, screenHeight);

    // Select the bitmap into the memory DC
    SelectObject(hdcMem, hBitmap);

    // BitBlt to copy the contents of the screen to the memory DC
    BitBlt(hdcMem, 0, 0, screenWidth, screenHeight, hdcScreen, 0, 0, SRCCOPY);

    // Release resources
    ReleaseDC(NULL, hdcScreen);
    DeleteDC(hdcMem);

    return hBitmap;
}

HBITMAP hCurrentScreen = GetScreenBitmap();
BitmapAngle BmAngle; BmAngle.Height = GetSystemMetrics(SM_CYSCREEN); BmAngle.Width = GetSystemMetrics(SM_CXSCREEN);
SaveBitmapToFile(hCurrentScreen, BmAngle, "TEST.bmp");
c++ winapi gdi stretchblt
1个回答
0
投票

感谢@IInspectable

换线即可

CreateCompatibleBitmap(hdcDest, NewAngle.Width, NewAngle.Height);

CreateCompatibleBitmap(hdcSrc, NewAngle.Width, NewAngle.Height);

会解决问题!

资源

© www.soinside.com 2019 - 2024. All rights reserved.