Setting scan coordinates in device options on pyinsane

671 views Asked by At

I use Sane's command line utility (scanimage) in order to scan films from the transparency unit of my scanner. Here is the command that I have been using with success:

scanimage --device-name pixma:04A9190D \
--source 'Transparency Unit' \
--resolution "4800" \
--format "tiff" \
--mode "color" \
-l "80.6" -x "56.2" -t "25.8" -y "219.2" \
> scan.tiff

I have decided to move this to Python code, using pyinsane in order to enable further integration with my image-processing workflow. This should supposedly give the following in Python code:

import pyinsane.abstract as pyinsane
device = pyinsane.get_devices()[0]

device.options['resolution'].value = 4800
device.options['mode'].value = 'Color'
device.options['source'].value = 'Transparency Unit'

# Setting coordinates to non-integers fails
device.options['tl-y'].value = 25.8
device.options['tl-x'].value = 80.6
device.options['br-y'].value = 219.2
device.options['br-x'].value = 56.2

scan_session = device.scan(multiple=False)
try:
    while True:
        scan_session.scan.read()
except EOFError:
    pass
image = scan_session.images[0]

But my first trials have been unsuccessful because I can not figure out how to set the scan coordinates pyinsane. As you see, I have found the appropriate options, but I don't know what unit they are in. scanimage takes the coordinates in millimetres by default, but pyinsane only takes integers. I have tried using pixel coordinates to no avail. I wonder what units the coordinate parameters take, and whether I am using them in the right order.

2

There are 2 answers

0
retrography On BEST ANSWER

pyinsane's option descriptions actually say the values are in milimeters:

Option: br-x
  Title: Bottom-right x
  Desc: Bottom-right x position of scan area.
  Type: <class 'pyinsane.rawapi.SaneValueType'> : Fixed (2)
  Unit: <class 'pyinsane.rawapi.SaneUnit'> : Mm (3)
  Size: 4
  Capabilities: <class 'pyinsane.rawapi.SaneCapabilities'> :[ Automatic, Soft_select, Soft_detect,]
  Constraint type: <class 'pyinsane.rawapi.SaneConstraintType'> : Range (1)
  Constraint: (0, 14160319, 0)
  Value: 20

But they are not! I divided the range maximum for br-x variable by the width of the scanning area of my scanner, and I got to the number 65536 (which is 2^16). Setting the coordinates to the millimetre value times 65536 works. Maybe these values define the number of steps of the stepper motor?

Also not that while scanimage interprets the -x and -y switches as width and length, and the -l and -t switches as offset, pyinsane takes bottom-right x (br-x), top-left y (tl-y), etc.

0
Jerome Flesch On

Pyinsane reports what Sane reports, as is. And Sane reports what the drivers report. In my experience, all the drivers don't behave exactly the same way, which may explain this weird unit (in other words, it could be a driver's bug). I never really worried about the unit before. I will check on my scanner what it says when I have some time..

Anyway I'm unsure why it does say 'mm', because in my experience, the unit here is actually always pixels (again, the documentation says it can be 'mm', so I need to check). If you want to scan a specific size, you should have a look at the resolution (dot per inch), and then do the math to figure out the size in pixels you expect.