Хорошо, вся история, я пытаюсь использовать Leptonica + Tesseract OCR на C++, чтобы сделать снимок экрана, сохранить его в * .bmp-файле, а затем загрузить его обратно в OCR с этим. Мне не нужно будет делать это часто, но поскольку я не могу копировать данные скриншота непосредственно в структуру PIX Leptonica, мне нужно сначала сохранить его в файл. Фактически, решение было бы предпочтительным.C++: Hbitmap/BITMAP в .bmp файл
Вот код, который я нашел онлайн, пытаясь помочь мне.
экрана крышка:
HBITMAP ScreenCapture(){
int width=100;
int height=100;
// get the device context of the screen
HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int x = GetDeviceCaps(hScreenDC, HORZRES);
int y = GetDeviceCaps(hScreenDC, VERTRES);
// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
//GlobalAlloc(GPTR, hBitmap)
WriteDIB(L"test.bmp", (HGLOBAL)hBitmap);
// clean up
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
return hBitmap;
// now your image is held in hBitmap. You can save it or do whatever with it
}
Попытка написать функцию:
BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB)
{
cout<<endl<<"Running save function";
/*HANDLE hDIB=GlobalAlloc(GPTR, sizeof(hDIBtochange));//this doesn't work, the result is four. Also the HANDLE parameter's name would be changed to hDIBtochange, so that the rest of the function uses the old 'hDIB' throughout
cout<<endl<<sizeof(hDIBtochange);*/
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
if (!hDIB)
return FALSE;
CFile file;
if(!file.Open(szFile, CFile::modeWrite|CFile::modeCreate))
return FALSE;
lpbi = (LPBITMAPINFOHEADER)hDIB;
int nColors = 1 << lpbi->biBitCount;
// Fill in the fields of the file header
hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
hdr.bfSize = GlobalSize (hDIB) + sizeof(hdr);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) (sizeof(hdr) + lpbi->biSize + nColors * sizeof(RGBQUAD));
// Write the file header
file.Write(&hdr, sizeof(hdr));
// Write the DIB header and the bits
file.Write(lpbi, GlobalSize(hDIB));
return TRUE;
}
бессовестно скопированный с постов людей на протяжении многих лет. Хорошо! Проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как GlobalAlloc Hbitmap в глобально доступную ручку, которую можно преобразовать или использовать с LPBITMAPINFOHEADER. Вскоре, когда lpbi создается, каждое отдельное поле внутри него является ошибкой «Невозможно прочитать память» в отладке Visual Studio 2012. Это недоступно, несмотря на то, что оно создано.
Solutions .. Идите прямо от ScreenCap к PIX, в памяти .. Найти способ сохранить растровое изображение и создавать их периодически читать .. Найти другой путь целиком, что делает больше смысла ..
Предпочитаю сначала, но, я прошу решения в этом, ко второму ... или третьему.
Если вам нужна дополнительная информация, я могу попытаться ее предоставить. Это в основном сводится к тому, что «я никогда раньше не делал такой код, и его не преподавали в моих классах, поэтому я стараюсь учиться, когда я иду».
Спасибо. Код других людей работал бы, если бы я мог понять это, но ваш был очень прост и сделал именно то, что мне было нужно. – user3285714
Добро пожаловать. GDI + существует уже более 10 лет и намного проще/лучше, чем DIY-решения для многих и многих других. – enhzflep