我正在处理与此相关的事情,并尝试使用您的代码以及来自此示例的代码:
http://www.codeproject.com/Tips/792316/WIA-Scanner-in-Csharp-Windows-Forms。
我在惠普扫描仪5590上测试了您的代码,它只能获取一张图像,即使我通过调试器逐步执行代码也是如此。第二次调用dialog.ShowTransfer时,会抛出ArgumentException并显示消息“值不在预期范围内”。我设法通过重置'image'和'dialog'对象并设置显式传输格式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>();
WIA.DeviceManager manager = new WIA.DeviceManager();
WIA.Device device = null;
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
if (info.DeviceID == scannerId)
{
device = info.Connect();
break;
}
}
if (device == null)
{
string availableDevices = "";
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
availableDevices += info.DeviceID + "\n";
}
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
{
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);
string fileName = Path.GetTempFileName();
File.Delete(fileName);
image.SaveFile(fileName);
try
{
Marshal.FinalReleaseComObject(image);
}
finally
{
image = null;
}
images.Add(Image.FromFile(fileName));
}
finally
{
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;
}
hasMorePages = false;
if (documentHandlingSelect != null)
{
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
{
List<string> devices = WIAScanner.GetDevices();
List<Image> images = null;
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();
}
}
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);
}
}