带有自动文档进纸器 (ADF) 的 C# WIA 在某些扫描仪上仅重新调整一页

Posted

技术标签:

【中文标题】带有自动文档进纸器 (ADF) 的 C# WIA 在某些扫描仪上仅重新调整一页【英文标题】:C# WIA with Automatic Document Feeder (ADF) retuns only one page on certain scanners 【发布时间】:2012-07-05 02:24:08 【问题描述】:

我有一台 HP Scanjet 7000(双面和 ADF 扫描仪)和一台 HP Scanjet 5500c(仅限 ADF)以及我正在开发的在 Windows 7 上使用 WIA 2.0 的扫描仪程序。

问题是代码在较旧的扫描仪型号上运行良好,但在较新的型号上,代码似乎在第一页上运行良好,然后在第二页上失败。如果我在下一行逐步执行代码;

image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatTIFF, false);

旧的扫描仪停止并等待对同一引用进行另一次调用,但新的扫描仪只是在一次连续操作中从进纸器运行它的所有页面。

我注意到,如果我在 Windows 7 中使用默认扫描程序,较新的程序会返回一个包含所有单独页面的 .tif 文件。旧版本返回单独的 .jpg 文件(每页一个)。

这向我表明,较新的扫描仪正在扫描整个进纸器,然后才准备好返回一组图像,而旧的扫描仪在扫描的每一页之间返回一个图像。

如何在代码中支持这种行为?以下是适用于旧扫描仪型号的相关代码的一部分:

public static List<Image> Scan(string scannerId)
    
        List<Image> images = new List<Image>();
        List<String> tmp_imageList = new List<String>();

        bool hasMorePages = true;
        bool useAdf = true;
        bool duplex = false;

        int pages = 0;

        string fileName = null;
        string fileName_duplex = null;

        WIA.DeviceManager manager = null;
        WIA.Device device = null;
        WIA.DeviceInfo device_infoHolder = null;
        WIA.Item item = null;
        WIA.ICommonDialog wiaCommonDialog = null;

        manager = new WIA.DeviceManager();

        // select the correct scanner using the provided scannerId parameter
        foreach (WIA.DeviceInfo info in manager.DeviceInfos)
        
            if (info.DeviceID == scannerId)
            
                // Find scanner to connect to
                device_infoHolder = info;        
                break;
            
        

        while (hasMorePages)
        
            wiaCommonDialog = new WIA.CommonDialog();              

            // Connect to scanner
            device = device_infoHolder.Connect();

            if (device.Items[1] != null)
            
                item = device.Items[1] as WIA.Item;

                try
                
                    if ((useAdf) || (duplex))
                        SetupADF(device, duplex); //Sets the right properties in WIA

                    WIA.ImageFile image = null;
                    WIA.ImageFile image_duplex = null;

                    // scan image                
                    image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatTIFF, false);

                    if (duplex)
                    
                        image_duplex = (ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatPNG, false);
                    

                    // save (front) image to temp file
                    fileName = Path.GetTempFileName();
                    tmp_imageList.Add(fileName);
                    File.Delete(fileName);
                    image.SaveFile(fileName);
                    image = null;               

                    // add file to images list
                    images.Add(Image.FromFile(fileName));

                    if (duplex)
                    
                        fileName_duplex = Path.GetTempFileName();
                        tmp_imageList.Add(fileName_duplex);
                        File.Delete(fileName_duplex);
                        image_duplex.SaveFile(fileName_duplex);
                        image_duplex = null;

                        // add file_duplex to images list
                        images.Add(Image.FromFile(fileName_duplex));
                    

                    if (useAdf || duplex)
                    
                        hasMorePages = HasMorePages(device); //Returns true if the feeder has more pages
                        pages++;                         
                    
                
                catch (Exception exc)
                
                    throw exc;
                
                finally
                
                    wiaCommonDialog = null;
                    manager = null;
                    item = null;
                    device = null;
                
            
        
        device = null;
        return images;
    

非常感谢您对此问题的任何帮助!我似乎无法在网上找到可行的解决方案。只是来自有同样问题的人的未答复的论坛帖子。

【问题讨论】:

我真希望我能看到你的“HasMorePages(device)”方法。我正在为那件作品苦苦挣扎。 【参考方案1】:

我们有一个非常相似的问题和各种解决方案,例如通过设置某些属性,没有帮助。主要问题是扫描仪 (ADF) 在启动时收回所有页面,而不管程序代码中发生了什么。 该过程反复导致错误,因为在扫描下一页之前“太多”了。这尤其适用于尝试另一个“连接”的事实。 为此,我们修改了代码,以便可以尽快读入各个页面:

public List<Image> Scan(string deviceID)
    
        List<Image> images = new List<Image>();

        WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
        WIA.Device device = this.Connect(deviceID);
        if (device == null)
            return images;

        WIA.Item item = device.Items[1] as WIA.Item;

        List<WIA.ImageFile> wiaImages = new List<ImageFile>();
        try
        
            // scan images
            do
            
                WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatJPEG, false);
                wiaImages.Add(image);
             while (true);
        
        catch (System.Runtime.InteropServices.COMException ex)
        
            if ((uint)ex.ErrorCode != WIA_PROPERTIES.WIA_ERROR_PAPER_EMPTY)
                throw ex;
        
        catch (Exception ex)
        
            throw ex;
        

        foreach (WIA.ImageFile image in wiaImages)
            this.DoImage(images, image);

        return images;
    

【讨论】:

【参考方案2】:

我看到您正在调用一个名为 SetupADF 的方法,该方法未显示,它可能会在设备对象上设置一些属性。您是否尝试过设置WIA_DPS_PAGES (property 3096) 和/或WIA_DPS_SCAN_AHEAD_PAGES (property 3094)?

我有一个blog post,关于从 Silverlight 中的 ADF 进行扫描,我相信评论者遇到了与您遇到的相同问题。将 WIA_DPS_PAGES 设置为 1 为他修复了它。我最终修改了代码的 SetDeviceProperties 方法,将 WIA_DPS_PAGES 设置为 1,将 WIA_DPS_SCAN_AHEAD_PAGES 设置为 0。

【讨论】:

【参考方案3】:

经过大量试验和错误后,我偶然发现了一个解决方案,该解决方案由于我不太确定的原因而起作用。 ShowTransfer() 方法似乎无法在扫描时将页面转换为 .png 或 .tiff 。将格式设置为 JPEG 或 BMP 实际上为我解决了这个问题:

image = (ImageFile)scanDialog.ShowTransfer(item, wiaFormatJPEG, false);

我想我在网上的某个地方看到,无论指定的格式如何,此方法实际上都会返回 BMP。与使用 bmp 或 jpeg 相比,将图像转换为 png 或 tiff 可能过于繁重。

在旁注中,我将属性设置:3088 设置为 0x005(adf 和双工模式)。

【讨论】:

这不是真正的解决方案,它会在不同的扫描仪中引发其他错误。 我收到此错误。你能帮我解决我做错了什么 错误:来自 HRESULT 的异常:0x8021006B 收到此错误。任何人都可以建议在 C# 中使用什么库来使用全原子双工扫描

以上是关于带有自动文档进纸器 (ADF) 的 C# WIA 在某些扫描仪上仅重新调整一页的主要内容,如果未能解决你的问题,请参考以下文章

WIA + 带有 adf = 1 页的网络扫描仪

WIA 2.0 复式属性

使用 WIA 自动进纸器扫描仪扫描第二页失败

通过进纸器进行 WIA 扫描

使用 NTwain 从进纸器扫描文档

无法读取通过 ADF 扫描的第二页