如何在不使用BitBlt的情况下提取HBITMAP的一部分

时间:2016-03-28 11:51:08

标签: c++ windows bitmap gdi hbitmap

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

我可以用BitBlt来做,但速度很慢。提取零件需要约50毫秒。 我已经考虑过提取从位图获得的字节数组的区域,但这似乎很难。还有其他办法吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

BitBlt非常快。如果你从另一个DC复制它需要一点时间。没有办法解决这个问题。

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

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

#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;
}

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