You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于WIA的网络扫描应用:单次仅扫一张图及进纸器/双面参数配置问题

WIA扫描应用ADF及双面扫描问题解决

问题描述

我正在开发一款基于WIA的网络扫描应用,目前遇到的问题是Transfer方法每次仅能扫描一张图像。我尝试强制设置参数WIA_DOCUMENT_HANDLING_SELECT = "3088",但结果仍是每次仅扫描一张图。请问该如何管理文档进纸器(ADF)及双面扫描参数?

我尝试的代码如下:

const string WIA_SCAN_COLOR_MODE = "6146";
const string WIA_HORIZONTAL_SCAN_RESOLUTION_DPI = "6147";
const string WIA_VERTICAL_SCAN_RESOLUTION_DPI = "6148";
const string WIA_HORIZONTAL_SCAN_START_PIXEL = "6149";
const string WIA_VERTICAL_SCAN_START_PIXEL = "6150";
const string WIA_HORIZONTAL_SCAN_SIZE_PIXELS = "6151";
const string WIA_VERTICAL_SCAN_SIZE_PIXELS = "6152";
const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
const string WIA_MANUFACTURER = "3";
const string WIA_DESCRIPTION = "4";
const string WIA_DOCUMENT_HANDLING_SELECT = "3088";
//const string WIA_LAMP_WARM_UP_TIME = "6161";
//const string WIA_IPS_DOCUMENT_HANDLING_SELECT =
//const string WIA_IPS_LAMP = 
const int widthA4at300dpi = 2480;
const int heightA4at300dpi = 3508;
const int widthA4at600dpi = 4960;
const int heightA4at600dpi = 7016;

public static Image scan(DeviceInfo dev, Protocol.ScannerOptions options)
{
    ImageFile imageFile = null;
    try
    {
        // Connect to the first available scanner
        Device device = dev.Connect();
        // Select the scanner
        Item scannerItem = device.Items[1];

        if(options.adf)
            SetWIAProperty(device.Properties, WIA_DOCUMENT_HANDLING_SELECT, 1); //1 is feeder 2 is flatbed
        AdjustScannerSettings(scannerItem, options.dpi, 0, 0, 1250, 1700, options.brightness, options.contrast, options.color_mode);

        imageFile = (ImageFile)scannerItem.Transfer(FormatID.wiaFormatBMP);
    }
    catch (COMException e)
    {
        // Convert the error code to UINT
        uint errorCode = (uint)e.ErrorCode;

        // See the error codes
        if (errorCode == 0x80210006)
        {
            Console.WriteLine("The scanner is busy or isn't ready");
            NetScanImageServer.txt_logger.write_log("The scanner is busy or isn't ready");
            throw new Exception("The scanner is busy or isn't ready");
        }
        else if (errorCode == 0x80210064)
        {
            Console.WriteLine("The scanning process has been cancelled.");
            NetScanImageServer.txt_logger.write_log("The scanning process has been cancelled.");
            throw new Exception("The scanning process has been cancelled.");
        }
        else if (errorCode == 0x8021000C)
        {
            Console.WriteLine("There is an incorrect setting on the WIA device.");
            NetScanImageServer.txt_logger.write_log("There is an incorrect setting on the WIA device.");
            throw new Exception("There is an incorrect setting on the WIA device.");
        }
        else if (errorCode == 0x80210005)
        {
            Console.WriteLine("The device is offline. Make sure the device is powered on and connected to the PC.");
            NetScanImageServer.txt_logger.write_log("The device is offline. Make sure the device is powered on and connected to the PC.");
            throw new Exception("The device is offline. Make sure the device is powered on and connected to the PC.");
        }
        else if (errorCode == 0x80210001)
        {
            Console.WriteLine("An unknown error has occurred with the WIA device.");
            NetScanImageServer.txt_logger.write_log("An unknown error has occurred with the WIA device.");
            throw new Exception("An unknown error has occurred with the WIA device.");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Errore SCANNER non pronto\n" + ex.ToString());
        NetScanImageServer.txt_logger.write_log("Errore SCANNER non pronto\n" + ex.ToString());
        throw new Exception("Errore SCANNER non pronto\n" + ex.ToString());
    }

    if(imageFile!=null)
        return ToBitmap(imageFile);
    else return null;
}

解决方案

1. 修正属性设置对象

WIA_DOCUMENT_HANDLING_SELECT属性需要设置在扫描项(Item)的Properties上,而非设备的Properties。修改代码中的设置逻辑:

if(options.adf)
    // 改为设置scannerItem的属性
    SetWIAProperty(scannerItem.Properties, WIA_DOCUMENT_HANDLING_SELECT, 1);

2. 正确设置ADF及双面扫描参数

根据WIA规范,WIA_DOCUMENT_HANDLING_SELECT的有效值:

  • 1:ADF单面扫描
  • 4:ADF双面扫描(需扫描仪硬件支持)
  • 2:平板扫描

设置前建议先检查扫描仪的WIA_DOCUMENT_HANDLING_CAPABILITIES属性,确认设备支持的模式,避免无效设置。

3. 循环扫描ADF所有页面

Transfer方法单次仅返回一张图像,要扫描ADF中所有页面,需循环调用Transfer,直到捕获到WIA_ERROR_PAPER_EMPTY(错误码0x8021000E),表示ADF已无纸张。修改方法返回List<Image>以支持多页:

public static List<Image> ScanADF(DeviceInfo dev, Protocol.ScannerOptions options)
{
    List<Image> scannedImages = new List<Image>();
    try
    {
        Device device = dev.Connect();
        Item scannerItem = device.Items[1];

        // 设置ADF模式(单面或双面)
        if(options.adf)
        {
            // 若支持双面,设置为4;否则设置为1
            SetWIAProperty(scannerItem.Properties, WIA_DOCUMENT_HANDLING_SELECT, options.doubleSided ? 4 : 1);
        }
        AdjustScannerSettings(scannerItem, options.dpi, 0, 0, 1250, 1700, options.brightness, options.contrast, options.color_mode);

        // 循环扫描直到ADF空
        while(true)
        {
            try
            {
                ImageFile imageFile = (ImageFile)scannerItem.Transfer(FormatID.wiaFormatBMP);
                scannedImages.Add(ToBitmap(imageFile));
            }
            catch(COMException e)
            {
                uint errorCode = (uint)e.ErrorCode;
                // 纸张为空,结束循环
                if(errorCode == 0x8021000E)
                {
                    break;
                }
                // 其他异常抛出
                throw;
            }
        }
    }
    catch (COMException e)
    {
        uint errorCode = (uint)e.ErrorCode;
        // 保留你原有的错误处理逻辑
        if (errorCode == 0x80210006)
        {
            Console.WriteLine("The scanner is busy or isn't ready");
            NetScanImageServer.txt_logger.write_log("The scanner is busy or isn't ready");
            throw new Exception("The scanner is busy or isn't ready");
        }
        // 其他错误处理...
    }
    catch (Exception ex)
    {
        Console.WriteLine("Errore SCANNER non pronto\n" + ex.ToString());
        NetScanImageServer.txt_logger.write_log("Errore SCANNER non pronto\n" + ex.ToString());
        throw new Exception("Errore SCANNER non pronto\n" + ex.ToString());
    }
    return scannedImages;
}

4. 补充双面扫描的额外设置

部分扫描仪需要额外设置WIA_DOCUMENT_HANDLING_STATUS或WIA_IPS_DOCUMENT_HANDLING_SELECT属性(针对WIA 2.0设备),如果使用WIA 2.0,建议优先使用WIA_IPS_DOCUMENT_HANDLING_SELECT(对应常量6144)而非旧版的3088。

内容的提问来源于stack exchange,提问作者DaX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 04:15:39