BACKGROUND TO THIS APPLICATION

Writing this app was motivated by the problem, that all scans performed with SimpleScan and two different Canon scanners were simply too dark. Other than my first approach, were I used Gambas as a frontend for the scanimage CLI-tool, I wanted to use the Gambas gb.Scanner component instead and realized a number of features in order to get a fully grown-up tool for the office or hobby. At some point it was decided to provide it as a sample project in the Gambas-Buch and to use it for the examination of the classes. All the knowledge gained with this app went into an according book chapter, which deals with the gb.scanner component.

First trials showed, that the gb.Scanner classes (written in Gambas) didn't work with my Canon brand scanners. The classes where apparently written with a HP scanner at hand and closer investigations of the classes and comparisons with my scanners showed, that there is a huge variance of parameters which have to be taken into account. The classes are well designed and deal with the huge variance, but there were small gaps, which were impossible to anticipate and required some modifications of the Scanner class while maintaining compatibility with the HP scanners.

These were my problems and my solutions/ modifications:

1. My Canon Pixma MG 6250 provides following information about its resolutions:
  --resolution auto||75|150|300|600|1200|2400|4800dpi [75]
This caused an error in the scanner class at following line in the GetOptions routine:
  hOption._MinValue = a[0]
It turned out that the class is not prepared for accepting non-number resolutions like "auto" and the options-parser seems to have an issue with a double "||". So I made following quick and dirty modification in order to be compatible with my Canon Pixma:
  If InStr(a[0], "|") Then a[0] = Split(a[0], "|")[1] 'Additional line
  hOption._MinValue = a[0]
There might be better ways to avoid the error but I didn't want to dive too deep into the complex and comprehensive options parser.

2. My second Canon scanner reports "Source" parameters, which the class is not prepared for. Besides others it provides "Normal" instead of "flatbed" in the following way:
  --source Normal|Transparency|Negative [inactive]
This is causing the sCount variable in the Function Scan() to remain empty which prevents the class from scanning.
  If InStr(LCase(Me["Source"].Value), "flatbed") Then
     sCount = "--batch-count=1"
     ...
So I modified this part in a way, that it always sets the batch-count=1 if an unsupported source option has been reported by the scanner:
  If InStr(LCase(Me["Source"].Value), "flatbed") Or Me["Source"].Value = "" Then
    sCount = "--batch-count=1"
    ...

3.  It further turned out, that the option-property 'isactive' is not working as one would expect. This is an issue in so far as the scan-process, which has been started with an inactive scanner option, is terminated immediately and the cli-tool scanimage throws an according error. Inactive scanner options can occor for two reason:
a) a combination of options don't match (i.e. "Threshold" is inactive in the mode "Color") or
b) the option is generally inactive (i.e. the "source" is always inactive at one of my scanners).
It seems, that non of the above has been taken into account for the 'isactive' property. Without knowing what really intended with the property 'isactive' I was hesitant to modify this property and since there was no other means to check for inactive options I decided to implement a dynamic check of some relevant options in the scanner class.
Something very important to know in this context is the fact, that the scanner class only sends those scan parameters to the scanimage cli-tool, which have been changed. So Only these modified scanner options are relevant for an 'inactive'-check. The status of the option-property 'modified' is set to True at any value written to the option. Hence and in order to minimize the scope of "inactive"-checks, which require some time, it is essential not to set a value of an option, if it is not required! This should carefully be considerd when setting parameters in the scan-start routine, i.e.:

  'Set threshold if available and has been modified
  If myScan.Exist("Threshold") Then
    If myScan["Threshold"].value <> SliderThreshold.value Then
      myScan["Threshold"].value = SliderThreshold.value
    End If
  End If

4.  One further issue was the lack of error message issued by the error event of the scanner class. As the errors were massively filtered I decided to extend the scope of error message through a littly ammendment in the error event. This required some enhanced filtering and targeted utilization. This modification was paricularely helpful when I started to deal with the 'inactive' scanner options.

5.  It turned out that the scanimage-option '--format=jpeg' used for scanning causes a compression of the scan. So it was modified to '--format=tiff' which leads to a clearly visible improvement of the image quality - but als to a slightly bigger size of the target file. The option -format=pnm also provides a very similar improvement but tiff showed colors which were closer to the scanned document. 

The modifications in the scanner-class are all marked with 'modified by claus' and are partially provided with some additional remarks. I am assuming that these modifications will not harm the original compatibility of the class. 

There are further three suggestions for modifications:
Public Sub Find(Key As String) As ScannerOption -> Public Sub Find((Key) As String) As ScannerOption
Public Sub Exist(Key As String) As Boolean -> Public Sub Exist((Key) As String) As Boolean
Static Private $IsInit As Boolean <- delete line

To the application itself:
Its comprehensive features and functions are inteded for real daily use, whether in the office or at home. The software can partially compensate lacks and bugs of the SANE API and might be particularily helpful for those who have Canon scanners. The app can even be applied with more than one scanner and all settings are stored and restored for each scanner individually.
If scans are too dark when using a canon scanner, try the Gamma setting. If this doesn't help use the Post-Scan enhancement dialogue, providing a slider for brigthness, contrast and gamma. In case of older faded photographs the checkbox "Equalize" may help, as it spreads the colors to a maximum color dynamic. The settings of these controls are also stored and restored for each scanner individually.
The app can optionally be remote controlled by a web interface which automatically adapts to the screen of a mobile phone or tablet if used for this purpose.

The application and the source code is provided under Creative Commons License and anybody may use an modify the app accordingly.

Known issues:
1. The "Source"-Combo is not considered in the scan process, which shouldn't be a problem for flatbed scanners.

Any feedback or discussion should be directed to the https://www.gambas-club.de/

All in all it must be said, that the gb.Scanner class is a comprehensive and great work.

Many thanks to Fabien Bodard.

Claus, Kiel, Germany Oct. 2023

