Преобразовать растровое изображение в PIX - PullRequest
0 голосов
/ 22 сентября 2019

я создаю приложение, которое делает снимок экрана монитора и затем читает его с помощью 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());

может кто-тообъясните мне, что я сделал не так?Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...