Pure python implementation of the libsane (using ctypes) and abstration layers.
It supports:
Libsane (part of the Sane) provides drivers for scanners under GNU/Linux and *BSD systems.
The code is divided in 2 layers:
Two workaround are provided:
$ sudo pip install pyinsane
or
$ git clone https://github.com/jflesch/pyinsane.git
$ cd pyinsane
$ sudo python3 ./setup.py install
$ python3 ./run_tests.py
Unit tests require at least one scanner with a flatbed and an ADF (Automatic Document Feeder).
If possible, they should be run with at least 2 scanners connected. The first that appear in "scanimage -L" must be the one with the ADF.
My current setup:
import pyinsane.abstract as pyinsane
devices = pyinsane.get_devices()
assert(len(devices) > 0)
device = devices[0]
print("I'm going to use the following scanner: %s" % (str(device)))
scanner_id = device.nameor if you already know its name/id:
import pyinsane.abstract as pyinsane
device = pyinsane.Scanner(name="somethingsomething")
print("I'm going to use the following scanner: %s" % (str(device)))device.options['resolution'].value = 300
# Beware: Some scanner have "Lineart" or "Gray" as default mode
device.options['mode'].value = 'Color'
scan_session = device.scan(multiple=False)
try:
while True:
scan_session.scan.read()
except EOFError:
pass
image = scan_session.images[0]if not "ADF" in device.options['source'].constraint:
print("No document feeder found")
return
device.options['source'].value = "ADF"
# Beware: Some scanner have "Lineart" or "Gray" as default mode
device.options['mode'].value = 'Color'
scan_session = device.scan(multiple=True)
try:
while True:
try:
scan_session.scan.read()
except EOFError:
print ("Got a page ! (current number of pages read: %d)"
% (len(scan_session.images)))
except StopIteration:
print("Document feeder is now empty. Got %d pages"
% len(scan_session.images))
for idx in range(0, len(scan_session.images)):
image = scan_session.images[idx]import pyinsane.abstract_th as pyinsane
# When imported, it will start a new thread, dedicated to Sane.
# Its API is the same than for pyinsane.abstract. You can use it the
# same way.
# Note however that the Sane thread can only do one thing at a time,
# so some function call may be on hold on a semaphore for some times.Some issues with some Sane drivers can become obvious in complex programs (uninitialized memory bytes, segfault, etc).
This module work around issues like the following one by using a dedicated process for scanning:
|
--> |
|
(see this comment for details)
Usage:
import pyinsane.abstract_th as pyinsaneWhen imported, it will create 2 Unix pipes (FIFO) in your temporary directory and a dedicated process. To avoid forking useless extra file descriptors, you should import this module as soon as possible in your program.
The folder 'examples' contains more detailed examples. For instance, examples/scan.py shows how to get pieces of a scan as it goes.
To run one of these scripts, run:
python -m examples.[script] [args]
For instance
python -m examples.scan toto.png
GPL v3 2012(c) Jerome Flesch (jflesch@gmail.com)