2016-03-28 25 views
-2

我有一個HBITMAP對象。如果不使用BitBlt,我想將它分成若干部分,並獲得這些部分的位或新位圖。如何在不使用BitBlt的情況下提取HBITMAP的一部分

我可以用BitBlt來做,但速度很慢。提取零件需要約50毫秒。 我已經考慮提取從位圖獲取的字節數組的區域,但這似乎很難。有沒有其他方法?

謝謝!

+0

請看這裏http://stackoverflow.com/a/35763157/4603670 –

+0

@BarmakShemirani:感謝您分享鏈接!我該如何擴展到複製區域?如果'HBITMAP'是1920X1080,我想用memcpy從字節數組中取500X500段。我仍然無法理解像素的排列。任何鏈接詳細說明?謝謝! – arch3r

+0

我發佈了鏈接到我自己的帖子,在那裏我解釋瞭如何直接訪問這些位。無論如何,'BitBlt'更快,更可靠,而且不需要50毫秒。顯示你已經做了什麼,所以我們可以看到它出錯的地方... –

回答

1

BitBlt非常快。如果你從另一個直流複製它需要一點點時間。沒有辦法解決這個問題。

到Word直接與像素需要GetDIBits(HDC hdc, HBITMAP hbitmap...)但你仍然需要BitBlt,以建立該hbitmap

您可以創建第二個內存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; 
} 

對於小的你已經表明它不應該直接訪問位,或使用第二個內存直流。您可以直接複製屏幕的任何部分,只需要操作1 BitBlt

相關問題