转换一个Windows位图到PIX(无符号字符缓冲区)

问题描述:

我正在一个窗口的屏幕截图,以便与Tesseract转换一个Windows位图到PIX(无符号字符缓冲区)

问题是与Leptonica到proccess它后来又做了一些OCR,性能明智我会就像避免将BMP写入和读取到光盘,而只是在内存中工作。这是我做的截图:

int width, height = 0; 

HDC hdcWindow; 
HDC hdcMemDC = NULL; 
HBITMAP hbmScreen = NULL; 
BITMAP bmpScreen; 

// Retrieve the handle to a display device context for the client 
// area of the window. 
//hdcScreen = GetDC(NULL); 
//hdcWindow = GetDC(hWnd); 

hdcWindow = GetDC(hWnd); 

// Create a compatible DC which is used in a BitBlt from the window DC 
hdcMemDC = CreateCompatibleDC(hdcWindow); 

if (!hdcMemDC) 
{ 
    MessageBox(hWnd, L"CreateCompatibleDC has failed", L"Failed", MB_OK); 
    goto done; 
} 

// Get the client area for size calculation 
RECT rcClient; 
GetClientRect(hWnd, &rcClient); 


// Create a compatible bitmap from the Window DC 
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); 

if (!hbmScreen) 
{ 
    MessageBox(hWnd, L"CreateCompatibleBitmap Failed", L"Failed", MB_OK); 
    goto done; 
} 

// Select the compatible bitmap into the compatible memory DC. 
SelectObject(hdcMemDC, hbmScreen); 

// Bit block transfer into our compatible memory DC. 
if (!BitBlt(hdcMemDC, 
    0, 0, 
    rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, 
    hdcWindow, 
    0, 0, 
    SRCCOPY)) 
{ 
    MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK); 
    goto done; 
} 

// Get the BITMAP from the HBITMAP 
GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen); 

BITMAPFILEHEADER bmfHeader; 
BITMAPINFOHEADER bi; 

bi.biSize = sizeof(BITMAPINFOHEADER); 
bi.biWidth = bmpScreen.bmWidth; 
bi.biHeight = bmpScreen.bmHeight; 
bi.biPlanes = 1; 
bi.biBitCount = 32; 
bi.biCompression = BI_RGB; 
bi.biSizeImage = 0; 
bi.biXPelsPerMeter = 0; 
bi.biYPelsPerMeter = 0; 
bi.biClrUsed = 0; 
bi.biClrImportant = 0; 

DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31)/32) * 4 * bmpScreen.bmHeight; 

// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
// have greater overhead than HeapAlloc. 
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize); 
char *lpbitmap = (char *)GlobalLock(hDIB); 

// Gets the "bits" from the bitmap and copies them into a buffer 
// which is pointed to by lpbitmap. 
GetDIBits(hdcWindow, hbmScreen, 0, 
    (UINT)bmpScreen.bmHeight, 
    lpbitmap, 
    (BITMAPINFO *)&bi, DIB_RGB_COLORS); 

// A file is created, this is where we will save the screen capture. 
HANDLE hFile = CreateFile(L"pics/UI.bmp", 
    GENERIC_WRITE, 
    0, 
    NULL, 
    CREATE_ALWAYS, 
    FILE_ATTRIBUTE_NORMAL, NULL); 

// Add the size of the headers to the size of the bitmap to get the total file size 
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 

//Offset to where the actual bitmap bits start. 
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); 

//Size of the file 
bmfHeader.bfSize = dwSizeofDIB; 

//bfType must always be BM for Bitmaps 
bmfHeader.bfType = 0x4D42; //BM 

DWORD dwBytesWritten = 0; 
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); 
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); 
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); 

//Unlock and Free the DIB from the heap 
GlobalUnlock(hDIB); 
GlobalFree(hDIB); 

//Close the handle for the file that was created 
CloseHandle(hFile); 

width = rcClient.right - rcClient.left; 
height = rcClient.bottom - rcClient.top; 

//Clean up 
done: 
DeleteObject(hbmScreen); 
DeleteObject(hdcMemDC); 
ReleaseDC(hWnd, hdcWindow); 

而且这是我读它:

PIX* pixUI = pixRead("pics/UI.bmp"); 

所以,我已经看到了库具有PIX * pixReadMemBmp (const l_uint8 *cdata, size_t size)method,这需要l_uint8这是一个unsigned char缓冲

的问题是,我不明白我怎么可以从我的HBITMAPBITMAP对象得到这样的缓冲。

先将位图复制到缓冲区,然后将此缓冲区交给pixReadMemBmp()。复制必须完成,因为我假设pixReadMemBmp()函数需要位图数据前面的两个位图标题,因为它在文件中。伪代码:

std::vector<unsigned char> buffer(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmpSize); 
std::copy(reinterpret_cast<unsigned char*>(&bmfHeader), reinterpret_cast<unsigned char*>(&bmfHeader) + sizeof(BITMAPFILEHEADER), buffer.begin()); 
std::copy(reinterpret_cast<unsigned char*>(&bi), reinterpret_cast<unsigned char*>(&bi) + sizeof(BITMAPINFOHEADER), buffer.begin() + sizeof(BITMAPFILEHEADER)); 
std::copy(lpbitmap, lpbitmap + dwBmpSize, buffer.begin() + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)); 
pixReadMemBmp(&buffer[0], buffer.size());