Skip to content

Commit

Permalink
add scan width and height, exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nagimov committed Feb 13, 2019
1 parent 526e78c commit a68c11a
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 65 deletions.
42 changes: 29 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ The utility is built around WIA (Microsoft Windows Image Acquisition Library). D
## Usage

```
Usage: wia-cmd-scanner [OPTIONS]...
All arguments are mandatory. Arguments must be ordered as follows:
/dpi {150,200,300,600} scan resolution, dots per inch
/color {RGB,GRAY,BW} scan color mode
/format {BMP,PNG,GIF,JPG,TIF} output image format
/output FILEPATH path to output image file
e.g.:
wia-cmd-scanner /dpi 300 /color RGB /format PNG /output .\scan.png
Usage: wia-cmd-scanner [OPTIONS]...
All arguments are mandatory. Arguments must be ordered as follows:
/w WIDTH width of the scan area, mm
/h HEIGHT height of the scan area, mm
/dpi RESOLUTION scan resolution, dots per inch
/color {RGB,GRAY,BW} scan color mode
/format {BMP,PNG,GIF,JPG,TIF} output image format
/output FILEPATH path to output image file
Use /w 0 and /h 0 for scanner-defined values, e.g. for receipt scanners
e.g. for A4 size black and white scan at 300 dpi:
wia-cmd-scanner /w 210 /h 297 /dpi 300 /color BW /format PNG /output .\scan.png
```

## Build
Expand All @@ -36,6 +40,18 @@ No Visual Studio project files are provided, since the code can be imported into

## Scripting and automation

Build your own automation tools around `wia-cmd-scanner.exe` binary using batch/powershell, or check out the source code.
You can build your own automation tools around `wia-cmd-scanner.exe` binary using batch/powershell. E.g. a simple batch job infinitely waiting for key press and scanning to a file with timestamp can be very simply achieved as follows:

```
@setlocal enabledelayedexpansion
:loop
@echo off
@for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
@set ldt=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2%_%ldt:~8,2%-%ldt:~10,2%-%ldt:~12,2%
@echo on
wia-cmd-scanner.exe /w 215.9 /h 279.4 /dpi 300 /color RGB /format PNG /output ..\scans\scan_%ldt%.png
pause
goto loop
```

The project is simple and tiny (~130 lines of VB code) and very easy to modify to fit your own needs.
For more sophisticated automated jobs, check out the source code. The project is very simple and easy to modify to fit your own needs.
164 changes: 112 additions & 52 deletions wia-cmd-scanner.vb
Original file line number Diff line number Diff line change
@@ -1,26 +1,62 @@
Module Module1

Sub printUsage()
Const version = "0.1"
Console.WriteLine("wia-cmd-scanner (version " & version & ") ")
Console.WriteLine("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> ")
Console.WriteLine(" ")
Console.WriteLine("Command-line scanner utility for WIA-compatible scanners ")
Console.WriteLine("Online help, docs & bug reports: <https://github.com/nagimov/wia-cmd-scanner/>")
Console.WriteLine(" ")
Console.WriteLine("Usage: wia-cmd-scanner [OPTIONS]... ")
Console.WriteLine(" ")
Console.WriteLine("All arguments are mandatory. Arguments must be ordered as follows: ")
Console.WriteLine(" ")
Console.WriteLine(" /dpi {150,200,300,600} scan resolution, dots per inch ")
Console.WriteLine(" /color {RGB,GRAY,BW} scan color mode ")
Console.WriteLine(" /format {BMP,PNG,GIF,JPG,TIF} output image format ")
Console.WriteLine(" /output FILEPATH path to output image file ")
Console.WriteLine(" ")
Console.WriteLine("e.g.: ")
Console.WriteLine(" wia-cmd-scanner /dpi 300 /color RGB /format PNG /output .\scan.png ")
Const version = "0.2"
Console.WriteLine("wia-cmd-scanner (version " & version & ") ")
Console.WriteLine("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> ")
Console.WriteLine(" ")
Console.WriteLine("Command-line scanner utility for WIA-compatible scanners ")
Console.WriteLine("Online help, docs & bug reports: <https://github.com/nagimov/wia-cmd-scanner/> ")
Console.WriteLine(" ")
Console.WriteLine("Usage: wia-cmd-scanner [OPTIONS]... ")
Console.WriteLine(" ")
Console.WriteLine("All arguments are mandatory. Arguments must be ordered as follows: ")
Console.WriteLine(" ")
Console.WriteLine(" /w WIDTH width of the scan area, mm ")
Console.WriteLine(" /h HEIGHT height of the scan area, mm ")
Console.WriteLine(" /dpi RESOLUTION scan resolution, dots per inch ")
Console.WriteLine(" /color {RGB,GRAY,BW} scan color mode ")
Console.WriteLine(" /format {BMP,PNG,GIF,JPG,TIF} output image format ")
Console.WriteLine(" /output FILEPATH path to output image file ")
Console.WriteLine(" ")
Console.WriteLine("Use /w 0 and /h 0 for scanner-defined values, e.g. for receipt scanners ")
Console.WriteLine(" ")
Console.WriteLine("e.g. for A4 size black and white scan at 300 dpi: ")
Console.WriteLine("wia-cmd-scanner /w 210 /h 297 /dpi 300 /color BW /format PNG /output .\scan.png")
End Sub

Sub printExceptionMessage(ex As Exception)
Dim exceptionDesc As New Dictionary(Of String, String)()
' see https://docs.microsoft.com/en-us/windows/desktop/wia/-wia-error-codes
exceptionDesc.Add("0x80210006", "Scanner is busy")
exceptionDesc.Add("0x80210016", "Cover is open")
exceptionDesc.Add("0x8021000A", "Can't communicate with scanner")
exceptionDesc.Add("0x8021000D", "Scanner is locked")
exceptionDesc.Add("0x8021000E", "Exception in driver occured")
exceptionDesc.Add("0x80210001", "Unknown error occured")
exceptionDesc.Add("0x8021000C", "Incorrect scanner setting")
exceptionDesc.Add("0x8021000F", "Unsupported scanner command")
exceptionDesc.Add("0x80210009", "Scanner is deleted and no longer available")
exceptionDesc.Add("0x80210017", "Scanner lamp is off")
exceptionDesc.Add("0x80210021", "Maximum endorser value reached")
exceptionDesc.Add("0x80210020", "Multiple page feed error")
exceptionDesc.Add("0x80210005", "Scanner is offline")
exceptionDesc.Add("0x80210003", "No document in document feeder")
exceptionDesc.Add("0x80210002", "Paper jam in document feeder")
exceptionDesc.Add("0x80210004", "Unspecified error with document feeder")
exceptionDesc.Add("0x80210007", "Scanner is warming up")
exceptionDesc.Add("0x80210008", "Unknown problem with scanner")
exceptionDesc.Add("0x80210015", "No scanners found")
For Each pair As KeyValuePair(Of String, String) In exceptionDesc
If ex.Message.Contains(pair.Key) Then
Console.WriteLine(pair.Value)
Exit Sub
End If
Next
Console.WriteLine("Exception occured: " & ex.Message)
End Sub


Sub Main()
' parse command line arguments
Dim clArgs() As String = Environment.GetCommandLineArgs()
Expand All @@ -30,17 +66,20 @@ Module Module1
Exit Sub
End If

If Not (clArgs(1) = "/dpi" And clArgs(3) = "/color" And clArgs(5) = "/format" And clArgs(7) = "/output") Then
If Not (clArgs(1) = "/w" And clArgs(3) = "/h" And clArgs(5) = "/dpi" And clArgs(7) = "/color" And clArgs(9) = "/format" And clArgs(11) = "/output") Then
printUsage()
Exit Sub
End If

Dim dpi As Integer = clArgs(2)
Dim color As String = clArgs(4)
Dim format As String = clArgs(6)
Dim output As String = clArgs(8)
' receive cmd line parameters
Dim w As Double = clArgs(2)
Dim h As Double = clArgs(4)
Dim dpi As Integer = clArgs(6)
Dim color As String = clArgs(8)
Dim format As String = clArgs(10)
Dim output As String = clArgs(12)

If Not (dpi = 150 Or dpi = 200 Or dpi = 300 Or dpi = 600) Then
If Not ((w = 0 And h = 0) Or (w > 0 And h > 0)) Then
printUsage()
Exit Sub
End If
Expand Down Expand Up @@ -85,26 +124,47 @@ Module Module1
End If

' scan the image
Dim DeviceManager = CreateObject("WIA.DeviceManager") ' create device manager
If DeviceManager.DeviceInfos.Count < 1 Then
Console.WriteLine("No compatible scanners found")
Exit Sub
End If
For i = 1 To DeviceManager.DeviceInfos.Count ' check all available devices
If DeviceManager.DeviceInfos(i).Type = 1 Then ' find first device of type "scanner" (exclude webcams, etc.)
Dim TimeStart = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)
Dim Scanner As WIA.Device = DeviceManager.DeviceInfos(i).connect ' connect to scanner
If IsNothing(Scanner) Then
Console.WriteLine("Scanner " & i & " not recognized")
Else
Console.WriteLine("Scanning to file " & output & " (dpi = " & dpi & ", color mode '" & color & "', output format '" & format & "')")
Try
Try

Dim DeviceManager = CreateObject("WIA.DeviceManager") ' create device manager
If DeviceManager.DeviceInfos.Count < 1 Then
Console.WriteLine("No compatible scanners found")
Exit Sub
End If
For i = 1 To DeviceManager.DeviceInfos.Count ' check all available devices
If DeviceManager.DeviceInfos(i).Type = 1 Then ' find first device of type "scanner" (exclude webcams, etc.)
Dim TimeStart = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)
Dim Scanner As WIA.Device = DeviceManager.DeviceInfos(i).connect ' connect to scanner
If IsNothing(Scanner) Then
Console.WriteLine("Scanner " & i & " not recognized")
Else
Console.WriteLine("Scanning to file " & output & " (dpi = " & dpi & ", color mode '" & color & "', output format '" & format & "')")
' set scan parameters
With Scanner.Items(1)
.Properties("6146").Value = colorcode
.Properties("6147").Value = dpi ' horizontal dpi
.Properties("6148").Value = dpi ' vertical dpi
End With
Dim props As New Dictionary(Of String(), Double)()
props.Add({"6146", "WIA_IPS_CUR_INTENT", "color mode"}, colorcode) ' color mode
props.Add({"6147", "WIA_IPS_XRES", "resolution"}, dpi) ' horizontal dpi
props.Add({"6148", "WIA_IPS_YRES", "resolution"}, dpi) ' vertical dpi
If w > 0 Then
props.Add({"6151", "WIA_IPS_XEXTENT", "width"}, w / 25.4 * dpi) ' width in pixels
props.Add({"6152", "WIA_IPS_YEXTENT", "height"}, h / 25.4 * dpi) ' height in pixels
props.Add({"6149", "WIA_IPS_XPOS", "exit"}, 0) ' x origin of scan area
props.Add({"6150", "WIA_IPS_YPOS", "exit"}, 0) ' y origin of scan area
End If
For Each pair As KeyValuePair(Of String(), Double) In props
Try
With Scanner.Items(1)
.Properties(pair.Key(0)).Value = pair.Value
End With
Catch ex As Exception
Console.WriteLine("Can't set property " & pair.Key(1))
If (pair.Key(2) <> "exit") Then
Console.WriteLine("Unsupported parameter, try scanning with different " & pair.Key(2))
Else
Console.WriteLine("Unknown issue, quitting")
End If
Exit Sub
End Try
Next
' scan image as BMP...
Dim Img As WIA.ImageFile = Scanner.Items(1).Transfer(wiaFormatBMP)
' ...and convert it to desired format
Expand All @@ -115,16 +175,16 @@ Module Module1
Img = ImgProc.Apply(Img)
' ...and save it to file
Img.SaveFile(output)
Catch ex As Exception
Console.WriteLine("Exception occured: " & ex.Message)
Exit Sub
End Try
End If
Dim TimeEnd = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)
Console.WriteLine("Scan finished in " & (TimeEnd - TimeStart) & " seconds")
Exit Sub ' if successfully found and scanned, quit
End If
Dim TimeEnd = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)
Console.WriteLine("Scan finished in " & (TimeEnd - TimeStart) & " seconds")
Exit Sub ' if successfully found and scanned, quit
End If
Next
Next
Catch ex As Exception
printExceptionMessage(ex)
Exit Sub
End Try
End Sub

End Module

0 comments on commit a68c11a

Please sign in to comment.