使用WIA和VB自动从同一台计算机上的多个扫描仪进行扫描



Hello堆栈溢出!

我是编程的终极初学者。我在php和vba方面有一些经验,可以根据需要编写自己的脚本,尤其是在excel中。

最近,对于一个正在进行的项目,我需要能够从连接到同一台计算机的多个扫描仪(例如2个用于初学者)自动扫描(比如每2分钟扫描一次)。我决定以这个项目为起点,让我感受一下Visual Basic。所以我们开始了,我安装了visualstudioexpress2010,并开始编写我的脚本,试图在这里和那里找到一些可以帮助我的代码。我发现WIA可以帮助我(Twain也可以,但对我这个新手来说,它似乎更模糊)

不管怎样,我终于想出了一个应用程序,当只连接一台扫描仪时,它可以在设定的时间间隔自动扫描。当我连接多个扫描仪时,问题就出现了。然后,第一次扫描正确进行(扫描仪1扫描,然后扫描仪2扫描),但当第二次扫描应该开始时,什么也没发生,扫描仪变得无法访问(繁忙)。我想也许我忘了"释放"或"断开"最后一台扫描仪。或者,扫描仪的缓冲存储器中还保留着什么?

在过去的三天里,我一直被这个问题困扰着,不知道如何让它发挥作用。

以下是扫描的功能:(我不会忽略其余部分,因为它是UI和文件夹管理)

Public Sub scannerloop()
'format constants
Const wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatPNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatGIF = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatTIFF = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"

'file format
Dim fileformat As String
If Me.FileExt.SelectedItem = "TIF" Then fileformat = wiaFormatTIFF
If Me.FileExt.SelectedItem = "JPEG" Then fileformat = wiaFormatJPEG
If Me.FileExt.SelectedItem = "BMP" Then fileformat = wiaFormatBMP
If Me.FileExt.SelectedItem = "PNG" Then fileformat = wiaFormatPNG
If Me.FileExt.SelectedItem = "GIF" Then fileformat = wiaFormatGIF
'colors
Dim colorcode As Integer
If Me.Colorbox.SelectedItem = "Black and white" Then colorcode = 4
If Me.Colorbox.SelectedItem = "Greyscale" Then colorcode = 2
If Me.Colorbox.SelectedItem = "Colour" Then colorcode = 1
'Resolution
Dim dpi As Integer
dpi = Me.dpiBox.SelectedItem
Dim horizextent = dpi * 8.2
Dim vertextent = dpi * 11.6

Dim j As String = 1
Dim DeviceManager1 = CreateObject("WIA.DeviceManager")   'wia device manager
For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
If DeviceManager1.DeviceInfos(i).Type = 1 Then  'Select only scanners, not webcams etc...
'startpoint to calculate how long it is to scan
Dim ScanStart = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)

'Directory + file
Dim targetdir = Me.ProjectFolderBox.Text & "scansScanner" & j & "S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
Form2.CurrentActionLabel.Text = "Scanning from scanner #" & j

Dim Scanner As WIA.Device = DeviceManager1.DeviceInfos(i).connect

If IsNothing(Scanner) Then
Log(Me.logfilename, Now & " | Scanner #" & j & " not found")
Else
Try
Dim Img As WIA.ImageFile
With Scanner.Items(1)
.Properties("6146").Value = colorcode '4 is Black-white,gray is 2, color 1 (Color Intent)
.Properties("6147").Value = dpi  'dots per inch/horizontal
.Properties("6148").Value = dpi 'dots per inch/vertical
.Properties("6149").Value = 0 'x point where to start scan
.Properties("6150").Value = 0 'y-point where to start scan
'Following is A4 paper size. (Not 100% accurate because real A4 Ht errors)
.Properties("6151").Value = horizextent 'horizontal exent DPI x inches wide
.Properties("6152").Value = vertextent 'vertical extent DPI x inches tall
'  .Properties("4104").Value = 8 'bits per pixel
End With
'transfer image
Img = Scanner.Items(1).Transfer(fileformat) 'scans the image.
'kill previous file if exists to avoid errors
If System.IO.File.Exists(targetdir) = True Then
Kill(targetdir)
End If
Img.SaveFile(targetdir)
'last scan
Form2.LastFileLabel.Text = "Scanner" & j & "S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
Form2.LastScanLabel.Text = Now
Catch ex As Exception
MsgBox(ex.Message)
Finally
Scanner = Nothing
End Try
End If
'End time for the scan
Dim ScanEnd = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " | Scanned " & targetdir & " | duration: " & (ScanEnd - ScanStart))
j = j + 1

Next
DeviceManager1 = Nothing

Me.CurrFileIndex = Me.CurrFileIndex + 1
Me.ScanCount = Me.ScanCount + 1
Me.NextScan = DateAdd("n", Me.IntervalBox.Value, Now)
Form2.ScanCountLabel.Text = Me.ScanCount
Form2.NextScanLabel.Text = Me.NextScan
Form2.CurrentActionLabel.Text = "Waiting..."
'Increment next file index and update in config file
Me.FileIndexBox.Value = Me.CurrFileIndex
SaveCfg()
End Sub

请原谅我,我知道这段代码可能是编程专业人士的噩梦,有很多不好的东西,但这确实是我的第一个VB程序,我很想学习。

所以基本上,程序的其余部分是一个表单,我在其中输入扫描的目标目录、文件名、分辨率等,当我点击"开始扫描"时,它-第一次运行scannerloop-启动一个"scantimer",每当它滴答作响时就会启动scannerloop。

正如我所说,它与1台扫描仪完美配合(按预期创建文件,更新日志文件等),但一旦我有了2台扫描仪,只有第一次扫描可以工作,然后,当扫描仪#1应该开始扫描时,它没有,扫描仪#2的led开始闪烁(就好像它在扫描,但它没有扫描)

我希望有人能帮助我。

提前谢谢。

Vince


UPDATE-我尝试过的可能感兴趣的事情:我只是试着添加一个for循环,使它从两个扫描仪扫描几次(所以,基本上独立于计时器和程序的其余部分):

Dim DeviceManager1 = CreateObject("WIA.DeviceManager")   'wia device manager
For k = 1 To 3
Dim j As String = 1
For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
[...]
Next i
Next k
DeviceManager1 = Nothing

这表明循环的第一次出现是有效的(每个扫描仪扫描一次),但仅此而已,扫描仪永远不会扫描第二次并开始闪烁,所以基本上是相同的问题。我还尝试在新循环中包含Devicemanager声明:

For k = 1 To 3 
Dim DeviceManager1 = CreateObject("WIA.DeviceManager")   'wia device manager
Dim j As String = 1
For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
[...]
Next i
DeviceManager1 = Nothing
Next k

但这并没有改变任何事情。

我做的下一件事是记录循环中的事件,这样我就可以知道事情到底停在哪里了:

Dim DeviceManager1=CreateObject("WIA.DeviceManager")'WIA设备管理器Dim j As String=1

For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
If DeviceManager1.DeviceInfos(i).Type = 1 Then  'Select only scanners, not webcams etc...
'startpoint to calculate how long it is to scan
Dim ScanStart = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)

'Directory + file
Dim targetdir = Me.ProjectFolderBox.Text & "scansScanner" & j & "S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
Form2.CurrentActionLabel.Text = "Scanning from scanner #" & j

Dim Scanner As WIA.Device = DeviceManager1.DeviceInfos(i).connect

If IsNothing(Scanner) Then
Log(Me.logfilename, Now & " | Scanner #" & j & " not found")
Else
Try
Dim Img As WIA.ImageFile
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " | Img initialized")
With Scanner.Items(1)
.Properties("6146").Value = colorcode '4 is Black-white,gray is 2, color 1 (Color Intent)
.Properties("6147").Value = dpi  'dots per inch/horizontal
.Properties("6148").Value = dpi 'dots per inch/vertical
.Properties("6149").Value = 0 'x point where to start scan
.Properties("6150").Value = 0 'y-point where to start scan
'Following is A4 paper size. (Not 100% accurate because real A4 Ht errors)
.Properties("6151").Value = horizextent 'horizontal exent DPI x inches wide
.Properties("6152").Value = vertextent 'vertical extent DPI x inches tall
'  .Properties("4104").Value = 8 'bits per pixel
End With
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " | properties initialized")
'transfer image
Img = Scanner.Items(1).Transfer(fileformat) 'scans the image.
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " |Transfer done")
'kill previous file if exists to avoid errors
If System.IO.File.Exists(targetdir) = True Then
Kill(targetdir)
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " | deleted existing " & targetdir)
End If
Img.SaveFile(targetdir)
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " | saved " & targetdir)
'last scan
Form2.LastFileLabel.Text = "Scanner" & j & "S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
Form2.LastScanLabel.Text = Now
Catch ex As Exception
MsgBox(ex.Message)
Finally
Scanner = Nothing
End Try
End If
'End time for the scan
Dim ScanEnd = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)
'log
Log(Me.logfilename, Now & " | Scanner #" & j & " | Scanned " & targetdir & " | duration: " & (ScanEnd - ScanStart))
j = j + 1
End If
Next i

这是生成的日志文件:

Scan starts 29/11/2012 9:24:31 AM | Interval :Start scanning with 5 min | Res:100 DPI | 
29/11/2012 9:24:31 AM | Scanner #1 | Img initialized
29/11/2012 9:24:31 AM | Scanner #1 | properties initialized
29/11/2012 9:24:49 AM | Scanner #1 |Transfer done
29/11/2012 9:24:49 AM | Scanner #1 | saved C:__2scansScanner1S1_img_1.TIF
29/11/2012 9:24:49 AM | Scanner #1 | Scanned C:__2scansScanner1S1_img_1.TIF | duration: 18
29/11/2012 9:24:49 AM | Scanner #2 | Img initialized
29/11/2012 9:24:49 AM | Scanner #2 | properties initialized
29/11/2012 9:25:08 AM | Scanner #2 |Transfer done
29/11/2012 9:25:08 AM | Scanner #2 | saved C:__2scansScanner2S2_img_1.TIF
29/11/2012 9:25:08 AM | Scanner #2 | Scanned C:__2scansScanner2S2_img_1.TIF | duration: 19
29/11/2012 9:25:08 AM | Scanner #1 | Img initialized
29/11/2012 9:25:08 AM | Scanner #1 | properties initialized

这一行似乎出了问题:

Img = Scanner.Items(1).Transfer(fileformat) 'scans the image.

看起来WIA很乐意从1号扫描仪切换到2号扫描仪,但拒绝回到1号扫描仪进行下一轮扫描。而且,我应该准确地说,当第二次扫描应该发生时,扫描仪#2会闪烁(而不是1,这让我感到惊讶)。是否有可能将扫描仪#2选择为"默认扫描仪"或类似的东西?如果是,有没有办法恢复?

谢谢你的帮助

扫描图像的代码:"不要忘记将wiaaut.DLL从windows\sys32添加到解决方案参考中。"首先检查扫描仪设备是否连接

Dim tempfile As String
Dim mydevice As WIA.Device
Dim item As WIA.Item
Dim imfile As WIA.ImageFile
Dim Commondialog1 As WIA.CommonDialog
sub check()
On Error Resume Next
Commondialog1 = New WIA.CommonDialog
mydevice = Commondialog1.ShowSelectDevice
MsgBox(mydevice.Type)
On Error GoTo Err_btnTakePicture_click
end sub
'then connect to scanner
sub scan()
'put the path and name for the location of your temp file here.
tempfile = ("d:filename.jpg")
'the next 4 lines deletes the old temp file if it exists
Dim filesystemobject = CreateObject("Scripting.FileSystemObject")
If filesystemobject.fileExists(tempfile) Then
Kill(tempfile)
End If
'the next two lines set up the configuration
Dim Commondialog1 As New WIA.CommonDialog
mydevice = Commondialog1.ShowSelectDevice
Dim wiaFormatJPEG As String = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
item = mydevice.Items(1)

imfile = DirectCast(Commondialog1.ShowTransfer(item, wiaFormatJPEG, False), WIA.ImageFile)
'this line saves the picture to a specified file
imfile.SaveFile(tempfile)

MsgBox("Picture taken")
PictureBox1.ImageLocation = tempfile
Exit_btnTakePicture_click:
mydevice = Nothing
item = Nothing
Exit Sub
Err_btnTakePicture_click:
MsgBox(Err.Description, vbOKOnly + vbCritical, "Error Taking Picture")
Resume Exit_btnTakePicture_click
end sub

相关内容

最新更新