L_LineRemoveBitmap returns 一个空的 HRGN

L_LineRemoveBitmap returns an empty HRGN

我正在尝试使用 Leadtools Version 20 自动清理一些图像(黑边去除、线条去除、歪斜校正等)。 由于某些 API 仅适用于黑白图像,因此我在内存中创建了图像的副本并使用 L_ColorResBitmap 将其变为黑白。我的计划是用这张黑白图像做处理,然后手动处理彩色图像。例如,我使用 L_BorderRemoveBitmap 找出需要擦除的区域,然后在彩色图像上擦除相同区域,或者使用 L_DeskewBitmap 找出黑白图像需要的角度转动然后使用 L_RotateBitmap 转动彩色图像。但是当我使用 L_LineRemoveBitmap 时,它 returns 是一个空白区域。我什至尝试使用回调函数,但回调函数区域内始终为 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;
}

萨姆,

如果你想让Callback设置一个Windows区域,你还需要在定义LINEREMOVE结构时设置LINE_CALLBACK_REGION uFlag:

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
};

标记已记录 in this page

函数完成处理后,您可以将lr.hRgn 属性中设置的线条区域使用以下代码设置在原始颜色位图中:

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

除了此处的回复之外,我还在回复您发送至我们支持地址的电子邮件中向您发送了一小段代码。