L_LineRemoveBitmap возвращает пустой HRGN - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь использовать Leadtools версии 20 для автоматической очистки некоторых изображений (удаление черной рамки, удаление линии, выравнивание, ...). Поскольку некоторые из API работают только с черно-белыми изображениями, я создаю копию изображения в памяти и превращаю его в черно-белое, используя L_ColorResBitmap. Я планирую использовать это черно-белое изображение для обработки, а затем обработать цветное изображение вручную. Например, я использую L_BorderRemoveBitmap, чтобы определить область, которую нужно стереть, а затем стереть ту же область на цветном изображении, или использую L_DeskewBitmap, чтобы определить угол, на который нужно повернуть черно-белое изображение, и затем использовать L_RotateBitmap чтобы включить цветное изображение. Но когда я использую L_LineRemoveBitmap, он возвращает пустую область. Я даже пытался использовать функцию обратного вызова, но внутри области функции обратного вызова всегда NULL.
Я убедился, что загружаемое изображение имеет вертикальную линию, а если я сохраню черно-белую версию, то линия удаляется, но правильный регион не возвращается.
Вот фрагмент того, что я делаю:

FILEINFO fi;
L_INT PageCount;
L_INT i;
L_UINT uFlags;
BITMAPHANDLE tBmp;
BITMAPHANDLE bwBmp;
BORDERREMOVE br = {sizeof(BORDERREMOVE), BORDER_SINGLE_REGION, BORDER_ALL, 25, 4, 10, NULL, nullptr, sizeof(BITMAPHANDLE)};
RECT r;
LINEREMOVE lr = {sizeof(LINEREMOVE), LINE_SINGLE_REGION, 400, 12, 15, 10, 2, 0, LINEREMOVE_VERTICAL, NULL, nullptr, sizeof(BITMAPHANDLE)};

memset(&fi, 0, sizeof(FILEINFO));
fi.uStructSize = sizeof(FILEINFO);
plo->PageNumber = 0; // plo is a LOADFILEOPTION*
L_FileInfo(FileName, &fi, sizeof(FILEINFO), FILEINFO_TOTALPAGES, plo); // ok
PageCount = fi.TotalPages;
for(i = 0; i < PageCount; i++)
{
    memset(&fi, 0, sizeof(FILEINFO));
    fi.uStructSize = sizeof(FILEINFO);
    plo->PageNumber = i + 1;
    memset(&tBmp, 0, sizeof(BITMAPHANDLE));
    FileInfo(FileName, &fi, sizeof(FILEINFO), 0, plo); // OK
    if(tBmp.Flags.Allocated)
        L_FreeBitmap(&tBmp);
    L_LoadBitmap(FileName, &tBmp, sizeof(BITMAPHANDLE), fi.BitsPerPixel > 24 ? 24 : fi.BitsPerPixel, ORDER_RGBORGRAY, plo, &fi); // OK
    if(tBmp.Flags.Allocated)
    {
        if (TOP_LEFT != tBmp.ViewPerspective)
            L_ChangeBitmapViewPerspective(NULL, &tBmp, sizeof(BITMAPHANDLE), TOP_LEFT);
        uFlags = DSKW_PROCESS | DSKW_FILL | DSKW_DOCUMENTANDPICTURE | DSKW_BICUBIC | DSKW_NORMALSPEEDROTATE;
        if(1 != fi.BitsPerPixel)
            uFlags |= (DSKW_DONT_PERFORM_PREPROCESSING | DSKW_NORMAL_DETECTION);
        memset(&BitmapRegion, 0, sizeof(BITMAPHANDLE));
        BitmapRegion.uStructSize = sizeof(BITMAPHANDLE);
        if(bwBmp.Flags.Allocated)
            L_FreeBitmap(&bwBmp);
        memset(&bwBmp, 0, sizeof(BITMAPHANDLE));
        bwBmp.uStructSize = sizeof(BITMAPHANDLE);
        L_CopyBitmap(&bwBmp, &tBmp, bwBmp.uStructSize); // OK
        if(1 != tBmp.BitsPerPixel)
            L_ColorResBitmap(&bwBmp, &bwBmp, sizeof(BITMAPHANDLE), 1, CRF_FIXEDPALETTE, NULL, NULL, 0, NULL, NULL); // OK
        L_BorderRemoveBitmap(&bwBmp, &br, nullptr, nullptr, 0) // OK
        if(NULL != br.hRgn)
        {
            L_SetBitmapRgnHandle(&tBmp, nullptr, br.hRgn, L_RGN_SET); // OK
            L_FillBitmap(&tBmp, bkColor); // OK bkColor is White
            L_FreeBitmapRgn(&tBmp);
        }
        L_LineRemoveBitmap(&bwBmp, &lr, lrCB, NULL, 0) // returns OK
        if(NULL != lr.hRgn) // not null but empty
        {
            ::GetRgnBox(lr.hRgn, &r); // it is always {0, 0, 0, 0}
            L_SetBitmapRgnHandle(&tBmp, nullptr, lr.hRgn, L_RGN_SET);
            L_FillBitmap(&tBmp, bkColor); // OK but fills nothing
            L_FreeBitmapRgn(&tBmp);
        }
        // do other stuff and save
    }
}

L_INT EXT_CALLBACK lrCB(HRGN hRgn, L_INT iStartRow, L_INT iStartCol, L_INT iLength, L_VOID* pUserData)
{
    UNREFERENCED_PARAMETER(pUserData);
    if(NULL != hRgn) // always null
    {
        RECT rcRect;

        GetRgnBox(hRgn, &rcRect);
        DeleteObject(hRgn);
    }
    return SUCCESS_REMOVE;
}

1 Ответ

0 голосов
/ 09 января 2019

Sam

Если вы хотите, чтобы Callback устанавливал регион Windows, вам также нужно установить uFlag LINE_CALLBACK_REGION при определении структуры LINEREMOVE:

LINEREMOVE lr = {
   sizeof(LINEREMOVE),                          // uStructSize
   LINE_CALLBACK_REGION| LINE_SINGLE_REGION,    // uFlags
   400,                                         // Minimum Length
   12,                                          // Maximum Width
   15,                                          // Wall size
   10,                                          // Max percent of line that can be a wall
   2,                                           // Maximum Gap
   0,                                           // Maximum Line Variance
   LINEREMOVE_VERTICAL,                         // horizontal or vertical
   NULL,                                        // hRgn 
   nullptr,                                     // pBitmapRegion
   sizeof(BITMAPHANDLE)                         // uBitmapStructSize
};

Флаг задокументирован на этой странице .

После того, как функция закончит обработку, вы можете взять область линий, заданную в свойстве lr.hRgn, и установить ее в исходном цветном растровом изображении, используя следующий код:

L_SetBitmapRgnHandle(&OriginalBitmap, NULL, lr.hRgn, L_RGN_SET);

В дополнение к ответу, приведенному здесь, я отправил вам небольшой фрагмент кода в ответ на электронное письмо, которое вы отправили на адрес нашей службы поддержки.

...