-2

我有一个 HBITMAP 对象。在不使用 BitBlt 的情况下,我想将它分成几部分并获得这些部分的位或新位图

我可以用 BitBlt 做到这一点,但它很慢。提取零件大约需要 50 毫秒。我考虑过从位图中提取字节数组的区域,但这似乎很困难。还有其他方法吗?

谢谢!

4

1 回答 1

1

BitBlt非常快。如果您是从另一个 dc 复制,则需要的时间太长。没有办法解决这个问题。

要直接使用您需要的像素,GetDIBits(HDC hdc, HBITMAP hbitmap...)但您仍然需要BitBlt设置hbitmap

您可以创建第二个内存 dc,从第一个内存 dc 复制到第二个内存 dc,这样会快得多。使用内存设备上下文就像直接访问位一样。

#include <iostream>
#include <windows.h>

using namespace std;

long long milliseconds()
{
    LARGE_INTEGER fq, t;
    QueryPerformanceFrequency(&fq);
    QueryPerformanceCounter(&t);
    return 1000 * t.QuadPart / fq.QuadPart;
}

int main()
{
    HWND hwnd = GetDesktopWindow();
    HDC hdc = GetDC(hwnd);
    HDC memdc = CreateCompatibleDC(hdc);
    RECT rc;
    GetWindowRect(hwnd, &rc);
    int width = rc.right - rc.left;
    int height = rc.bottom - rc.top;

    int xPos = 100;
    int yPos = 100;
    int cropWidth = 500;
    int cropHeight = 500;

    HBITMAP hbitmap = CreateCompatibleBitmap(hdc, width, height);
    SelectObject(memdc, hbitmap);

    long long start;

    start = milliseconds();
    BitBlt(memdc, 0, 0, cropWidth, cropHeight, hdc, xPos, yPos, SRCCOPY);
    //this will take about 50 ms, or much less
    cout << milliseconds() - start << "\n"; 

    {
        //create a second memory dc:
        start = milliseconds();
        HDC memdc2 = CreateCompatibleDC(hdc);
        HBITMAP hbitmap2 = CreateCompatibleBitmap(memdc2, 500, 500);
        SelectObject(memdc2, hbitmap2);
        BitBlt(memdc2, 0, 0, 500, 500, memdc, 0, 0, SRCCOPY);

        //this will take about 1 ms:
        cout << "time: " << milliseconds() - start << "\n";
        DeleteObject(hbitmap2);
        DeleteDC(memdc2);
    }

    DeleteDC(memdc);
    DeleteObject(hbitmap);
    ReleaseDC(hwnd, hdc);

    return 0;
}

对于您所展示的小型设备,无需直接访问位或使用第二个内存 dc。您可以直接复制屏幕的任何部分,只需 1BitBlt次操作。

于 2016-04-02T05:14:23.320 回答