- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用具有自动进纸器的扫描仪扫描多页。目前我的代码非常简单:
WIA.CommonDialog dialog = new WIA.CommonDialog();
WIA.Device device = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType);
WIA.Items items = dialog.ShowSelectItems(device);
foreach (WIA.Item item in items)
{
while (true)
{
try
{
WIA.ImageFile image = (WIA.ImageFile)dialog.ShowTransfer(item);
if (image != null && image.FileData != null)
{
dynamic binaryData = image.FileData.get_BinaryData();
if (binaryData is byte[])
using (MemoryStream stream = new MemoryStream(binaryData))
using (Bitmap bitmap = (Bitmap)Bitmap.FromStream(stream))
{
bitmap.Save(@"C:\Temp\scan.jpg", ImageFormat.Jpeg);
}
}
}
catch (COMException)
{
break;
}
}
}
我尝试查询 WIA_DPS_DOCUMENT_HANDLING_STATUS
属性以查看馈送器中是否有任何可用页面,但总是返回 1,所以如果我得到 WIA_ERROR_PAPER_EMPTY
,我知道文档进纸器是空的。
问题是这段代码只扫描了第一页,当 dialog.ShowTransfer
方法再次被调用时,我得到一个异常和 E_FAIL
HResult 并且我可以' 扫描更多页面。奇怪的是,当我在调试器中单步执行这段代码时,一切正常,所有页面都被扫描了。
我尝试通过执行 Marshal.ReleaseComObject(image)
和 image = null
释放图像对象,但这没有帮助。 this question 的建议也没有.是不是我做错了什么导致了这些错误?
编辑:我无法为此找到好的解决方案。当进纸器准备扫描下一页时,扫描仪不断抛出 E_FAIL
,这需要几秒钟(它不是一个非常快的扫描仪)。因此,我添加了一个循环以继续尝试 10 秒,这是一个我不喜欢的解决方案,但它似乎有效。
编辑 2:这似乎是打印机的 WIA 驱动程序的问题。我用不同品牌的打印机试过,完全没有这个问题。
最佳答案
我正在做同样的事情,并尝试使用您的代码和本示例中的代码:http://www.codeproject.com/Tips/792316/WIA-Scanner-in-Csharp-Windows-Forms
我在 hp scanjet 5590 上测试了您的代码,即使我在调试器中单步执行代码,它也只能获取一张图像。在第二次调用时,dialog.ShowTransfer 抛出 ArgumentException 并显示消息“值不在预期范围内。”我设法通过重置“图像”和“对话框”对象并设置显式传输格式 ID 使其工作。您的代码还将图像写入同一文件。如果应用于您的代码,这对我有用:
WIA.CommonDialog dialog = new WIA.CommonDialog();
WIA.Device device = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType);
WIA.Items items = dialog.ShowSelectItems(device);
foreach (WIA.Item item in items)
{
while (true)
{
WIA.ImageFile image = null;
try
{
dialog = new WIA.CommonDialog();
image = (WIA.ImageFile)dialog.ShowTransfer(item,"{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}", false);
if (image != null && image.FileData != null)
{
dynamic binaryData = image.FileData.get_BinaryData();
if (binaryData is byte[])
using (MemoryStream stream = new MemoryStream(binaryData))
using (Bitmap bitmap = (Bitmap) Bitmap.FromStream(stream))
{
bitmap.Save(String.Format(@"C:\Temp\scan{0}.jpg", Path.GetRandomFileName()),
ImageFormat.Jpeg);
}
}
}
catch (COMException)
{
break;
}
finally
{
if (image != null)
Marshal.FinalReleaseComObject(image);
}
}
}
该 CodeProject 示例在我的硬件上也失败了,但同样的修复有帮助。如果上面的代码仍然不适合你试试,用这个替换原来的 Scan 方法:
public static List<Image> Scan(string scannerId)
{
List<Image> images = new List<Image>();
// select the correct scanner using the provided scannerId parameter
WIA.DeviceManager manager = new WIA.DeviceManager();
WIA.Device device = null;
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
if (info.DeviceID == scannerId)
{
// connect to scanner
device = info.Connect();
break;
}
}
// device was not found
if (device == null)
{
// enumerate available devices
string availableDevices = "";
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
availableDevices += info.DeviceID + "\n";
}
// show error with available devices
throw new Exception("The device with provided ID could not be found. Available Devices:\n" + availableDevices);
}
WIA.Item item = null;
WIA.CommonDialog dialog = new WIA.CommonDialog();
WIA.Items items = dialog.ShowSelectItems(device);
if (items == null)
return images;
item = items[1];
bool hasMorePages = true;
while (hasMorePages)
{
try
{
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);
// save to temp file
string fileName = Path.GetTempFileName();
File.Delete(fileName);
image.SaveFile(fileName);
try
{
Marshal.FinalReleaseComObject(image);
}
finally
{
image = null;
}
// add file to output list
images.Add(Image.FromFile(fileName));
}
finally
{
//determine if there are any more pages waiting
WIA.Property documentHandlingSelect = null;
WIA.Property documentHandlingStatus = null;
foreach (WIA.Property prop in device.Properties)
{
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}
// assume there are no more pages
hasMorePages = false;
// may not exist on flatbed scanner but required for feeder
if (documentHandlingSelect != null)
{
// check for document feeder
if ((Convert.ToUInt32(documentHandlingSelect.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_SELECT.FEEDER) != 0)
{
hasMorePages = ((Convert.ToUInt32(documentHandlingStatus.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_STATUS.FEED_READY) != 0);
}
}
}
}
return images;
}
也用这个替换 btn_scan_Click 方法:
private void btn_scan_Click(object sender, EventArgs e)
{
try
{
//get list of devices available
List<string> devices = WIAScanner.GetDevices();
List<Image> images = null;
//check if device is not available
if (devices.Count == 0)
{
MessageBox.Show("You do not have any WIA devices.");
this.Close();
}
else
{
if (devices.Count == 1)
{
images = WIAScanner.Scan(devices[0]);
}
else
{
images = WIAScanner.Scan();
}
}
//get images from scanner
foreach (Image image in images)
{
var path = String.Format(@"C:\Temp\scan{0}_{1}.jpg", DateTime.Now.ToString("yyyy-MM-dd HHmmss"), Path.GetRandomFileName());
image.Save(path, ImageFormat.Jpeg);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
关于c# - 使用 WIA 自动进纸器扫描仪扫描第二页失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32708547/
需要帮助将这些给定的数字打印成星号,但我是编程新手;我该怎么做? #include int main(void) { int a[5]={20,1,5,15,12}; int i=0
使用 Delphi XE 2 我试图确定缩放方向以将缩放效果应用于图像(TImage),但没有找到执行此操作的函数,并且图像的 OnGesture 事件中的 EventInfo 属性没有此信息. 我见
我不知道制服在内存中是如何表示的。 制服似乎会占用宝贵的寄存器空间,但它们最终会传入/通过/传出到全局内存中,对吗? 制服不用时情况会发生变化吗?编译器可以将它们优化掉吗?--在这种情况下,我已经将无
我正在尝试在名为“timeclock”的模型上记录“time_in”和“time_out”记录。这是我想做但无法开始工作的事情! 检查最后一个时钟条目,看看它是否同时填充了“time_in”和“tim
我想听听您如何解决这种编程任务!?每种类型(OPER = 1 类型)对应一种特定的信息。 这只是大约 10 个具有相同结构的规范之一。首选创建这些“转换器”(协议(protocol))的通用方法。 最
我正在使用 Rest API(NodeJS、Express)和 PostgreSQL 制作 React-Native 应用。 在我的本地机器上托管时一切正常。当 API 托管在我的机器上并且 Post
我是一名优秀的程序员,十分优秀!