-2

HBITMAP オブジェクトがあります。BitBlt を使用せずに、それをパーツに分割し、これらのパーツのビットまたは新しいビットマップを取得したいと思います

BitBlt でできますが、遅いです。パーツの抽出には約 50 ミリ秒かかります。ビットマップから取得したバイト配列の領域を抽出することも考えましたが、難しそうです。他に方法はありますか?

ありがとう!

4

1 に答える 1

1

BitBltは非常に高速です。別の DC からコピーしている場合は、少し時間がかかりすぎます。それを回避する方法はありません。

必要なピクセルを直接言葉にするにはGetDIBits(HDC hdc, HBITMAP hbitmap...)、まだBitBlt設定する必要がありますhbitmap

2 番目のメモリ DC を作成し、最初のメモリ DC から 2 番目のメモリ 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;
}

あなたが示した小さなものについては、ビットに直接アクセスしたり、2番目のメモリDCを使用したりする必要はありません。画面の任意の部分を直接コピーできます。必要なBitBlt操作は 1 回だけです。

于 2016-04-02T05:14:23.320 に答える