1

我正在尝试使用 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;
}
4

1 回答 1

1

山姆,

如果你想让 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
};

该标志记录在此页面中。

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

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

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

于 2019-01-09T17:44:33.780 回答