я создаю приложение, которое делает снимок экрана монитора и затем читает его с помощью tesseract.Чтобы получить более высокую производительность, например, избегайте сохранения снимка экрана перед его отправкой в tesseract.
Я нашел несколько примеров и других связанных постов и пришел к этому коду, который использует «pixReadMemBm», но он всегда возвращает нулевой ptr:
#define _CRT_SECURE_NO_WARNINGS // for strncopy and fopen
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
//include leptonica headers
#include <allheaders.h>
//include tesseract headers
#include <baseapi.h>
using namespace std;
TCHAR CurDir[MAX_PATH];
tesseract::TessBaseAPI *api;
void init_tesseract_ocr();
PIX* tesseract_preprocess(PIX* pixs);
string tesseract_ocr(PIX* image);
PIX* ScreenShot(int left, int top, int sizex, int sizey);
int main()
{
GetCurrentDirectory(MAX_PATH, CurDir);
init_tesseract_ocr();
PIX* sc = ScreenShot(0, 0, 500, 30);
//PIX* pp = tesseract_preprocess(sc);
//string text = tesseract_ocr(pp);
//cout << text << endl;
system("pause");
return 0;
}
PIX* ScreenShot(int left, int top, int sizex, int sizey)
{
// get the device context of the screen
HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBitmap;
hBitmap = CreateCompatibleBitmap(hScreenDC, sizex, sizey);
// get a new bitmap
SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, sizex, sizey, hScreenDC, left, top, SRCCOPY);
BITMAP bmpScreen;
GetObject(hBitmap, 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;
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
GetDIBits(hScreenDC, hBitmap, 0,
(UINT)bmpScreen.bmHeight,
lpbitmap,
(BITMAPINFO *)&bi, DIB_RGB_COLORS);
// 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
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*HANDLE hFile = CreateFile("UI.bmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
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);
//Close the handle for the file that was created
CloseHandle(hFile);*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////
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));
PIX *mypix = pixReadMemBmp(&buffer[0], buffer.size());
if (mypix == NULL)
{
cout << "mypix is NULL" << endl;
}
else
{
pixWriteImpliedFormat("preprocess.bmp", mypix, 0, 0);
}
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
DeleteObject(hBitmap);
GlobalUnlock(hDIB);
GlobalFree(hDIB);
/////////////////////////////////////
return mypix;
}
если я сохраню снимок экрана в файл (с методами, прокомментированными в коде), я получу ожидаемый результат, поэтому проблема в этих 5 строках:
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));
PIX *mypix = pixReadMemBmp(&buffer[0], buffer.size());
может кто-тообъясните мне, что я сделал не так?Спасибо!