【问题标题】:Detecting the camera that scanned image belongs to检测扫描图像所属的相机
【发布时间】:2021-01-01 23:10:09
【问题描述】:

我正在使用 Leadtools 20 API 来控制扫描仪并扫描一些文档。我有 2 个问题。
1 - 当使用带有回调函数的 L_TwainAcquire 时,该函数从扫描仪接收图像并不断返回 SUCCESS 以获取下一张图像。回调函数内部是否有确定图像是来自前置摄像头还是后置摄像头的方法?
2 - 有没有办法强制扫描仪仅使用后置摄像头进行扫描?

谢谢
山姆

【问题讨论】:

    标签: c++ leadtools-sdk


    【解决方案1】:

    如果您是指使用双面扫描仪时扫描文档的两面,答案如下:

    1. 要知道位图回调中当前正在处理纸张的哪一面,可以在回调函数内部使用如下代码:
    L_INT EXT_CALLBACK LTwainBitmapCallback(HTWAINSESSION hSession, pBITMAPHANDLE pBitmap, L_VOID * pUserData)
    {
       L_INT nRet = SUCCESS;
       TW_EXTIMAGEINFO* pExtImg = NULL;
       int nExtraInfoAftreZero = 0;  // we have only one info, so no extra needed
       pExtImg = (TW_EXTIMAGEINFO *)malloc(sizeof TW_EXTIMAGEINFO  + nExtraInfoAftreZero * sizeof TW_INFO);
       if (pExtImg)  
       { 
          pExtImg->NumInfos = 1;
          pExtImg->Info[0].InfoID = TWEI_PAGESIDE;
          pExtImg->Info[0].ItemType = TWTY_UINT16;
          nRet = L_TwainGetExtendedImageInfo (hSession, pExtImg); 
          if (nRet == SUCCESS) 
          { 
             // Do processing to returned values
             if(pExtImg->Info[0].Item == TWCS_TOP)
                OutputDebugString("Front of sheet.\n");
             else if (pExtImg->Info[0].Item == TWCS_BOTTOM)
                OutputDebugString("Rear of sheet.\n");
             else
                OutputDebugString("Unexpected!\n");
             nRet = L_TwainFreeExtendedImageInfoStructure (&pExtImg); 
             if(nRet != SUCCESS) 
                return nRet; 
          }
          free(pExtImg);
       }
       return SUCCESS;
    }
    
    1. 可以结合使用 CAP_CAMERASIDE 和 CAP_CAMERAENABLED 功能来强制扫描特定的一面,如 Twain Spec 中所述。

    引用该文档:

    要启用仅底部扫描,请将 CAP_CAMERASIDE 设置为 TWCS_BOTTOM 并 将 CAP_CAMERAENABLED 设置为 TRUE,然后将 CAP_CAMERASIDE 设置为 TWCS_TOP 并 将 CAP_CAMERAENABLED 设置为 FALSE。

    如果您的意思是您有一台带有 2 个 Twain 摄像头源(背面和正面)的计算机,则答案如下:

    1. 要知道在调用L_TwainAcquire() 时哪个 Twain 源(例如相机)触发了 Twain 位图回调,您可以使用 带有LTWAIN_SOURCE_ENUMERATE_DEFAULT 标志的L_TwainGetSources() 函数可获取当前选定的吐温设备。这可以在位图回调内部完成,如以下代码所示:
    // Source Info Callback
    L_INT EXT_CALLBACK TwainSourceInfoCallbackCurrent(HTWAINSESSION hSession, pLTWAINSOURCEINFO pSourceInfo, L_VOID * pUserData)
    {
       strcpy((L_CHAR *)pUserData, pSourceInfo->pszTwnSourceName);
       return SUCCESS;
    }
    
    // Twain Bitmap Callback
    L_INT EXT_CALLBACK LTwainBitmapCallback(HTWAINSESSION hSession, pBITMAPHANDLE pBitmap, L_VOID * pUserData)
    {
       char szSourceName[1024];
       L_TwainGetSources(hSession, TwainSourceInfoCallbackCurrent, sizeof LTWAINSOURCEINFO, LTWAIN_SOURCE_ENUMERATE_DEFAULT, szSourceName);
       // Now szSourceName contains name of Twain Source.
       return SUCCESS;
    }
    
    1. 是的,您可以通过在扫描前将其名称发送到L_TwainSelectSource() 函数来强制从特定设备(扫描仪、相机等)进行扫描,如下所示:
    LTWAINSOURCE TwainSource;
    TwainSource.uStructSize = sizeof LTWAINSOURCE;
    TwainSource.pszTwainSourceName = pszRearCameraTwainSourceName;
    L_TwainSelectSource(twainSession, &TwainSource);
    // Now L_TwainAcquire() will capture from Rear Camera
    

    要查找所有设备的名称,您可以使用以下代码:

    L_TwainGetSources(twainSession, TwainSourceInfoCallback, sizeof LTWAINSOURCEINFO, LTWAIN_SOURCE_ENUMERATE_ALL, NULL);
    

    每个 Twain 源都会触发一次源信息回调。可以这样实现:

    L_INT EXT_CALLBACK TwainSourceInfoCallback(HTWAINSESSION hSession, pLTWAINSOURCEINFO pSourceInfo, L_VOID * pUserData)
    {
       OutputDebugString(pSourceInfo->pszTwnSourceName); // You can save the names of Twain Sources into global variables if you like
       OutputDebugString("\n");
       return SUCCESS;
    }
    

    【讨论】:

    • 我想我可能还不够清楚我需要什么。我知道L_TwainSelectSource()。它为您提供了所选扫描仪的名称,但这不是我需要的。有时扫描仪内部有 2 个摄像头并同时扫描页面的两侧(如 Fujitsu fi-7900),并且回调被调用两次。一次用于纸的顶部,一次用于纸的底部。我需要找出: 1- 前面或后面调用了回调?和 2- 强制扫描仪只扫描页面的背面。我认为这与使用TWFY_CAMERABOTTOM 有关,但我不确定如何。
    • 已修改答案以涵盖您的问题,以及可能对其他人有用的原始答案。
    • 感谢编辑的答案。它有点回答了我的第二个问题并指出了我L_TwainGetExtendedImageInfo() 这可能会回答第一个问题。我可以在位图回调中使用L_TwainGetExtendedImageInfo() 来获取页面端吗?如果是,您能否修改答案以显示它是如何完成的?提前谢谢你。
    • 再次更新。很抱歉,我们没有在第一次编辑中涵盖您的所有问题。
    • 是的,我们需要释放 2 个东西。 TW_EXTIMAGEINFO 结构是用 malloc() 分配的,所以我们需要在完成后调用 free()。 (或者使用 GlobalAlloc 和 GlobalFree 等)但是在释放它之前,我们必须释放其中的 TW_INFO Info[] 数组,该数组由 L_TwainGetExtendedImageInfo() 分配,因此我们必须在 TW_EXTIMAGEINFO 结构本身被释放之前调用 L_TwainFreeExtendedImageInfoStructure()。
    猜你喜欢
    • 2014-11-17
    • 2011-01-29
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多