Продолжение цикла статей:
Часть 1. Разбираемся со сканерами в Linux: получение информации об устройстве и поиск подходящего драйвера.
Часть 2. Разбираемся со сканерами в Linux: Установка и конфигурирование устройства
В третьей части продемонстрируем различные сценарии использования среды для сканирования SANE.
Методы ускорения поиска устройств
В целях унификации и поддержки как можно большего списка устройств, в стандартную сборку libsane1 включены все доступные бэкенды. Каждый запуск фронтенда инициирует поиск и загрузку этих файлов, считывание сотни строк в десятках конфигурационных файлах, не говоря уже о шторме сетевого трафика при поиске сетевых устройств. Время, затраченное на поиск устройства, увеличивается на n sec с каждого вызова локального и сетевого бэкенда.
Сократить время поиска, а, следовательно, и запуска фронтенда можно несколькими способами:
исключить или закомментировать из /etc/sane.d/dll.conf и /etc/sane.d/dll.d строки с неиспользуемыми бэкендами
-
в каждом оставшемся конфигурационном файле бэкенда
отключить поиск сетевых устройств, если есть такая возможность;
ограничить список сетевых устройств, опять же, если есть такая возможность;
оставить записи с идентификаторами VID и PID только необходимых устройств.
Для информации
По умолчанию, в /etc/sane.d/dll.conf перечислено 92 бэкенда. 15 из них, устаревших и уже закомментированы. Также, в /etc/sane.d/dll.d/ присутствует 1 бэкенд hpaio. Итого, 93 активных бэкенда.
-
при стандартных настройках, поиск устройств под пользователем занимает 7,5 сек
time scanimage -L
time scanimage -L
real 0m7,569s
исключение hpaio, сократит время выполнения на 1,1 секунду
отключение устаревших бэкендов для поддержки SCSI-устройств, а также подключенных по параллельному порту - прироста в скорости не дает
самые "жирные" бэкенды, которые тратят больше всего времени на выполнение, - magicolor, kodakaio, epson, epsonds. Без них, поиск занимает под пользователем 2 (две) секунды
Строго говоря, внесение правок в конфигурационные .conf файлы для управления списком бэкендов и моделей - не самое лучшее решение. Более "гибкий" вариант - использование комбинаций конфигурационных файлов dll.conf и <backend_name>.conf, собранных вместе в отдельной директории. В этом случае можно "на горячую" задавать списки бэкендов и устройств при запуске фронтенда через переменную SANE_CONFIG_DIR.
К примеру, так будет выглядеть конфигурация под говорящим названием sane_kyocera с двумя моделями устройств, использующих разные бэкенды:
tree /opt/sane_kyocera/
/opt/sane_kyocera/
├── kyocera_wc3_usb.conf
├── kyocera.conf
└── dll.conf
Где файлы бэкендов /opt/sane_kyocera/kyocera.conf и /opt/sane_kyocera/kyocera_wc3_usb.conf содержат упоминание лишь по одной модели,
/opt/sane_kyocera/kyocera.conf
#Kyocera MFP supported device
# FS-1320 MFP
usb 0x0482 0x04FE
/opt/sane_kyocera/kyocera_wc3_usb.conf
# Kyocera WC3 supported device
# ECOSYS M2040dn
usb 0x0482 0x069d
а также, разумеется, упоминание этих бэкендов в dll.conf.
/opt/sane_kyocera/dll.conf
kyocera
kyocera_wc3_usb
Запуск выполняется следующим образом:
SANE_CONFIG_DIR=/opt/sane_kyocera scanimage -L
В такой конфигурации выполнение scanimage с указанием пути до каталога с конфигурационными файлами поможет сократить время запуска до n sec. Или оно может применяться для тестовых задач, не затрагивая основную конфигурацию. Минимального времени запуска можно добиться:
оставив строку с единственным бэкендом pantum6500 в /etc/sane.d/dll.conf;
оставив одну запись в pantim6500.conf об idVendor и idProduct устройства.
Значение переменной можно импортировать как одному пользователю,
echo "SANE_CONFIG_DIR=/opt/sane_kyocera" | tee -a /home/<username>/.profile
так и для всех пользователей системы.
echo "SANE_CONFIG_DIR=/opt/sane_kyocera" | sudo tee -a /etc/environment
Конфигурации могут храниться централизованно, и администратор получит удобный инструмент для управления поиска устройств на рабочих станциях.
Есть и другое решение, не требующее вмешательства в конфигурационные файл, - запуск фронтенда с указанием имени устройства. При таком запуске этап поиска всеми бэкендами будет пропущен и по факту произойдёт считывание всех конфигурационных файлов из /etc/sane.d/dll.conf; /etc/sane.d/dll.d, а инициализация только целевого бэкенда
fly-scan -d pantum6500:libusb:001:003
[22:55:34.470452] [dll] sane_open: trying to open `pantum6500:libusb:001:003'
[22:55:34.470592] [dll] load: searching backend `pantum6500' in `/usr/lib/x86_64-linux-gnu/sane:/usr/lib/sane:/usr/lib64/sane'
[22:55:34.470720] [dll] load: trying to load `/usr/lib/x86_64-linux-gnu/sane/libsane-pantum6500.so.1'
[22:55:34.470939] [dll] load: dlopen()ing `/usr/lib/x86_64-linux-gnu/sane/libsane-pantum6500.so.1'
[22:55:34.480892] [dll] init: initializing backend `pantum6500'
[22:55:34.507091] [dll] init: backend `pantum6500' is version 1.0.13
[22:55:34.507266] [dll] init: backend `pantum6500' initialization completed in 26 ms
Не все утилиты сканирования это поддерживают, но в scanimage и fly-scan возможность запуска с параметром -d (device name) есть. Даже simple-scan принимает имя устройства в формате simple-scan <device_name>. На время запуска может также оказывать влияние "тяжесть" фронтенда. fly-scan отрисует готовое к работе окно интерфейса за 1,5 секунд.
Справочное руководство scanimage (sane-utils)
Рассмотрим все доступные параметры scanimage и приведем примеры с их использованием в различных сценариях. Всё это уже доступно по команде man scanimage.
Процесс сканирования
Сканирование представляет собой линейный процесс, в котором сперва выполняем поиск доступных сканирующих устройств. Затем запрашиваем список доступного функционала (-A) и проверяем работоспособность устройства при помощи серии тестов (-T). Последним этапом выполняем сканирование с настройками бэкенда по умолчанию.
Используемые параметры сканирования
-L, --list-devices
Поиск устройств. При поиске будут использованы все бэкенды, перечисленные в /etc/sane.d/dll.conf и /etc/sane.d/dll.d. В результате выполнения получим список обнаруженных устройств в виде:
scanimage -L
device `escl:https://10.0.0.120:9096' is a ESCL Kyocera ECOSYS M2540dn platen,adf scanner
device `escl:https://10.0.12.21:443' is a ESCL Pantum BM5100ADW Series 4B94CA platen,adf scanner
device `pantum6500:tcp 10.0.12.21 9200-BM5100ADW' is a Pantum BM5100ADW (tcp 10.0.12.21 9200-BM5100ADW)
device `airscan:e0:Kyocera ECOSYS M2540dn' is a eSCL Kyocera ECOSYS M2540dn ip=10.0.0.120
device `airscan:e1:Pantum BM5100ADW Series 4B94CA' is a eSCL Pantum BM5100ADW Series 4B94CA ip=10.0.12.21
-f format, --formatted-device-list=format
Управление форматом вывода имен найденных устройств. При использовании параметра -f добавлять поиск устройств -L не требуется. Доступные квантификаторы:
%d - имя устройства
%v - вендор (производитель)
%m - модель
%t - тип сканирующего устройства
%i - порядковый номер (начинается с 0)
%n - перенос строки
Вывод списка найденных устройств с заданным форматом:
scanimage -f "%i: Найден %t, имя устройства %d; производитель %v; модель %m%n"
0: Найден multi-functional device, имя устройства kyocera_wc3_usb:libusb:001:002; производитель Kyocera; модель ECOSYS M2540dn
1: Найден platen,adf scanner, имя устройства escl:https://10.0.0.120:9096; производитель ESCL; модель Kyocera ECOSYS M2540dn
2: Найден platen,adf scanner, имя устройства escl:https://10.0.12.21:443; производитель ESCL; модель Pantum BM5100ADW Series 4B94CA
3: Найден , имя устройства pantum6500:tcp 10.0.12.21 9200-BM5100ADW; производитель ; модель Pantum BM5100ADW (tcp 10.0.12.21 9200-BM5100ADW)
4: Найден ip=10.0.0.120, имя устройства airscan:e0:Kyocera ECOSYS M2540dn; производитель eSCL; модель Kyocera ECOSYS M2540dn
5: Найден ip=10.0.12.21, имя устройства airscan:e1:Pantum BM5100ADW Series 4B94CA; производитель eSCL; модель Pantum BM5100ADW Series 4B94CA
-A, --all-options
Вывод всех возможностей бэкенда.
Внимание! Возможностей именно бэкенда, а не устройства. Выполнение команды не приведёт к сканированию. Например:
scanimage -A
All options specific to device `kyocera_wc3_usb:libusb:001:002':
Standard:
--source Auto|DP|Platen|2-sided (Binding Top)|2-sided (Binding Left/Right) [Auto]
Selects the scan source (such as a document-feeder).
--mode Mono|Gray|Color [Mono]
Selects the scan mode (e.g., lineart, monochrome, or color).
--resolution 200|300|400|600dpi [200]
Sets the resolution of the scanned image.
Advanced:
--originalSize A4|A5|A6|B5(JIS)|B5(ISO)|B6|Legal|Letter|Executive [A4]
Original Size options
--sendingSize Auto|A4|A5|A6|B5(JIS)|B5(ISO)|B6|Legal|Letter|Executive [Auto]
Sending Size options
--imageQuality Text|Photo|Text+Photo [Text+Photo]
Image Quality options
--densityType Manual|Auto [Manual]
Density type options
--density -3..3 (in steps of 1) [0]
Density options
--page-height 0..23330816mm [0] [read-only]
Specifies the height of the media.
--page-width 0..14155776mm [0] [read-only]
Specifies the width of the media. Required for automatic centering of
sheet-fed scans.
В квадратных скобках указаны значения описанных параметров, установленные по умолчанию.
h, --help
Справка о возможностях scanimage. Помимо этого, параметр --help выведет аналогичную scanimage -A информацию. Но время выполнения займет больше времени, так как в конце будет произведен поиск устройств. По сути, выполнение равноценно scanimage -A -L
scanimage --help
Usage: scanimage [OPTION]...
Start image acquisition on a scanner device and write image data to
standard output.
Parameters are separated by a blank from single-character options (e.g.
-d epson) and by a "=" from multi-character options (e.g. --device-name=epson).
-d, --device-name=DEVICE use a given scanner device (e.g. hp:/dev/scanner)
--format=pnm|tiff|png|jpeg|pdf file format of output file
-i, --icc-profile=PROFILE include this ICC profile into TIFF file
-L, --list-devices show available scanner devices
-f, --formatted-device-list=FORMAT similar to -L, but the FORMAT of the output
can be specified: %d (device name), %v (vendor),
%m (model), %t (type), %i (index number), and
%n (newline)
-b, --batch[=FORMAT] working in batch mode, FORMAT is `out%d.pnm' `out%d.tif'
`out%d.png' or `out%d.jpg' by default depending on --format
This option is incompatible with --output-file. --batch-start=# page number to start naming files with
--batch-count=# how many pages to scan in batch mode
--batch-increment=# increase page number in filename by #
--batch-double increment page number by two, same as
--batch-increment=2
--batch-print print image filenames to stdout
--batch-prompt ask for pressing a key before scanning a page
--accept-md5-only only accept authorization requests using md5
-p, --progress print progress messages
-o, --output-file=PATH save output to the given file instead of stdout.
This option is incompatible with --batch.
-n, --dont-scan only set options, don't actually scan
-T, --test test backend thoroughly
-A, --all-options list all available backend options
-h, --help display this help message and exit
-v, --verbose give even more status messages
-B, --buffer-size=# change input buffer size (in kB, default 32)
-V, --version print version information
Output format is not set, using pnm as a default.
Options specific to device `katusham247:192.168.10.24':
--resolution 75|100|150|200|300|600dpi [300]
Sets the resolution of the scanned image.
Geometry:
--Paper size Letter|Executive|A4|A5|B5|Statement|Custom [Letter]
-l 0..216mm [0]
Top-left x position of scan area.
-t 0..293mm [0]
Top-left y position of scan area.
-x 0..216mm [216]
Width of scan-area.
-y 0..293mm [293]
Height of scan-area.
--source Flatbed|Automatic Document Feeder|ADF Duplex [Flatbed]
Selects the scan source (such as a document-feeder).
--preview[=(yes|no)] [no]
Request a preview-quality scan.
--mode Lineart|Gray|Color [Gray]
Selects the scan mode (e.g., lineart, monochrome, or color).
Enhancement:
--halftoning Threshold|Error Diffusion [Threshold]
--brightness -60..60 (in steps of 1) [0]
Controls the brightness of the acquired image.
--contrast -20..20 (in steps of 1) [0]
Controls the contrast of the acquired image.
Type ``scanimage --help -d DEVICE'' to get list of all options for DEVICE.
List of available devices:
katusham247:192.168.10.24 katusham247:libusb:001:002
-d, --device-name
Имя используемого устройства. Значение может быть скопировано из вывода scanimage -L или в случае использования псевдонимов - короткое имя (alias) устройства. Если имя устройства не указать, scanimage считает имя устройства из переменной SANE_DEFAULT_DEVICE (по умолчанию, переменная не задана). Если переменная не задана, будет использовано первое найденное устройство.
Имя устройства (DeviceURI), содержащее пробелы, необходимо заключить в двойные, или одинарные кавычки. Имени устройства также соответствует квантификатор %d при использовании параметра -f
. Примеры использования:
scanimage -d escl:https://10.0.0.20:443 -A
scanimage -d kyocera_wc3_usb:libusb:001:002 -A
scanimage -d "airscan:e1:Pantum BM5100ADW Series 4B94CA" -A
SANE_DEFAULT_DEVICE=kyocera_wc3_usb:libusb:001:002 scanimage -A
export SANE_DEFAULT_DEVICE=kyocera_wc3_usb:libusb:001:002 && scanimage -A
-i profile, --icc-profile=profile
Применить к отсканированной копии tiff-файла цветового профиля. Параметр - путь к файлу .icc. Например:
scanimage -d "pantum6500:tcp 10.0.12.21 9200-BM5100ADW" --format tiff --batch=p%04d.tiff -p --resolution 150 -i ../Canon_iP4300_InkTec_C908_LomondSGloss260.icm --batch-count=1
-p, --progress
Процесс выполнения задания сканирования в процентах. Информация отображается при консольном выполнении scanimage для каждой сканируемой страницы. Не ожидайте отображения статуса выполнения в реальном времени от сетевых бэкендов, только для локальных (USB, SCSI) устройств.
-n, --dont-scan
Выполнение команд scanimage без сканирования. Например, для передачи устройству особых команд: сброс счетчика скан-копий, установка таймера выключения и прочее, в зависимости от возможностей бэкенда.
-T, --test
Тестирование функционала бэкенда с устройством используя SANE API. Результат выполнения не всегда говорит об исправности устройства, так как разные вендоры демонстрируют разный результат. Запуск scanimage -T приведет устройство в рабочий режим и выполнит тестовое сканирование (проход лампы) без выходного файла. Например, вывод команды с заведомо исправных устройств Pantum BM5100ADW (pantum6500:tcp):
scanimage -d "pantum6500:tcp 10.0.12.21 9200-BM5100ADW" -T
Output format is not set, using pnm as a default.
scanimage: scanning image of size 2550x3507 pixels at 24 bits/pixel
scanimage: acquiring RGB frame, 8 bits/sample
scanimage: reading one scanline, 7650 bytes... PASS
scanimage: reading one byte... PASS
scanimage: stepped read, 2 bytes... PASS
scanimage: stepped read, 4 bytes... PASS
scanimage: stepped read, 8 bytes... PASS
scanimage: stepped read, 16 bytes... PASS
scanimage: stepped read, 32 bytes... PASS
scanimage: stepped read, 64 bytes... PASS
scanimage: stepped read, 128 bytes... PASS
scanimage: stepped read, 256 bytes... PASS
scanimage: stepped read, 512 bytes... PASS
scanimage: stepped read, 1024 bytes... PASS
scanimage: stepped read, 2048 bytes... PASS
scanimage: stepped read, 4096 bytes... PASS
scanimage: stepped read, 8192 bytes... PASS
scanimage: stepped read, 8191 bytes... PASS
scanimage: stepped read, 4095 bytes... PASS
scanimage: stepped read, 2047 bytes... PASS
scanimage: stepped read, 1023 bytes... PASS
scanimage: stepped read, 511 bytes... PASS
scanimage: stepped read, 255 bytes... PASS
scanimage: stepped read, 127 bytes... PASS
scanimage: stepped read, 63 bytes... PASS
scanimage: stepped read, 31 bytes... PASS
scanimage: stepped read, 15 bytes... PASS
scanimage: stepped read, 7 bytes... PASS
scanimage: stepped read, 3 bytes... PASS
и Kyocera M2540dn (kyocera_wc3_usb)
scanimage -d "kyocera_wc3_usb:libusb:001:002" -T
Output format is not set, using pnm as a default.
scanimage: scanning image of size 1653x2338 pixels at 1 bits/pixel
scanimage: acquiring gray frame, 1 bits/sample
scanimage: reading one scanline, 207 bytes... PASS
scanimage: reading one byte... FAIL No data
scanimage: stepped read, 2 bytes... FAIL No data
scanimage: stepped read, 4 bytes... FAIL No data
scanimage: stepped read, 8 bytes... FAIL No data
scanimage: stepped read, 16 bytes... FAIL No data
scanimage: stepped read, 32 bytes... FAIL No data
scanimage: stepped read, 64 bytes... FAIL No data
scanimage: stepped read, 128 bytes... FAIL No data
scanimage: stepped read, 256 bytes... PASS
scanimage: stepped read, 255 bytes... PASS
scanimage: stepped read, 127 bytes... FAIL No data
scanimage: stepped read, 63 bytes... FAIL No data
scanimage: stepped read, 31 bytes... FAIL No data
scanimage: stepped read, 15 bytes... FAIL No data
scanimage: stepped read, 7 bytes... FAIL No data
scanimage: stepped read, 3 bytes... FAIL No data
--accept-md5-only
Принимать запросы на авторизацию только с использованием MD5 для передачи логина\пароля в зашифрованном виде. Порядок настройки авторизации для доступа к бэкендам на сервере saned описан в статье Saned. Подключение удаленного сканера.
-B, --buffer-size=#
Размер входного буфера в килобайтах. Справка выводит информацию об установленном значении по умолчанию в 32 кб. Начиная с версии SANE Backends 1.3.1, размер буфера по умолчанию уже установлен в 1Мб. Малый размер буфера может оказывать негативное влияние на производительность сканирования и тянется со времен слабых ПК.
--format=format
Указание формата выходного файла (stdout) или расширения файла, заданного в параметром --output-file. Доступные форматы: pnm, tiff, png, jpeg и pdf. Если значение не задано, файл будет сохранен в pnm.
-V, --version
Вывести информацию о версии sane-backends и scanimage как его части.
-v, --verbose
Вывод отладочной информации о работе scanimage. Пожалуй, самый бесполезный параметр. Для вывода отладочной информации используются переменные окружения SANE_DEBUG_<BACKENDNAME>=LOGLEVEL. Например:
SANE_DEBUG_DLL=255 SANE_DEBUG_KYOCERA_WC3_USB=255 scanimage -L
-o path, --output-file=path
Сохранение выходного изображения в файл. Параметр несовместим с --batch. Если разрешение файла не задано, будет ошибка
Could not guess output format from the given path and no --format given.
Примеры использования
# Сканирование в файл с указанием расширения при помощи --format
scanimage -d 'kyocera_wc3_usb:libusb:001:004' --format=jpeg -o scan_copy
file scan_copy
scan_copy: JPEG image data, JFIF standard 1.01, resolution (DPI), density 200x200, segment length 16, baseline, precision 8, 1653x2338, components 1
# Сканирование в файл с расширением
scanimage -d 'kyocera_wc3_usb:libusb:001:004' -o scan_copy.jpeg
scan_copy.jpeg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 200x200, segment length 16, baseline, precision 8, 1653x2338, components 1
--batch*
Все параметры batch предназначены для сканирования через АДП (АПД дуплекс).
-b [format], --batch=[format]
Формат сохраняемых файлов. Каждая страница будет сохранена в отдельный файл. Если формат не задан, по умолчанию будет использован формат out%d.pnm. При указании формата, имя файла будет выглядеть:
out%d.tiff для --format=tiff
out%d.png для --format=png
out%d.jpg для --format=jpeg
out%d.pdf для --format=pdf
Параметр не совместим с --output-path. Используемый формат имен совместим с форматом функции printf c одним целочисленным параметром.
Если файл с создаваемым именем уже есть в текущем каталоге, он будет перезаписан. Для сокращения набора параметров расширение файла можно указывать в самом параметре, не задавая дополнительно --format . Кроме этого, в роли имени файла можно использовать результат выполнения команд, в этом случае значение заключается в одинарные скобки.
Примечание. На самом деле, возможно передать более двух параметров, но значения будут начинаться не с "1" (если счетчик не задан иным через параметр --batch-start ) - вместо этого, счетчик будет представлять рандомное 10-значное число.
Примеры:
# Использование устройства kyocera_wc3_usb:libusb:001:004 по-умолчанию
export SANE_DEFAULT_DEVICE=kyocera_wc3_usb:libusb:001:004
# Не задан формат имен файлов
scanimage -b --format=pdf --source='Automatic Document Feeder'
file out1.pdf
# Формат не задан, будет сохранен по умолчанию в pnm
scanimage --batch=scan%d
file scan1
scan1: Netpbm image data, size = 1653 x 2338, rawbits, bitmap
# Самая короткая запись, файл сохранен в pdf
scanimage --batch=scan%d.pdf
file scan1
scan1: PDF document, version 1.3
# Имя выходного файла без расширения, но в формате pdf
scanimage --batch=scan%d --format=pdf
$ file scan1
$ scan1: PDF document, version 1.3
# Избыточное указание параметров, но всё же допустимо
$ scanimage --batch=scan%d.pdf --format=pdf
$ file scan1.pdf
scan1.pdf: PDF document, version 1.3
# Если указан --format, его значение будет иметь высший приоритет
scanimage --batch=scan%d.pdf --format=jpeg
file scan1.pdf
scan1.pdf: JPEG image data, JFIF standard 1.01, resolution (DPI), density 200x200, segment length 16, baseline, precision 8, 1653x2338, components 1
# Использование двух переменных удобно для генерации уникального имени
scanimage --batch=scan%d%d.pdf
scan12045603552.pdf
# Использование date для создания уникального имени файла\ов
scanimage --batch=$(date +%Y%m%d_%H%M%S)_p%d.pdf
20241004_223757_p1.pdf
# Форматирование имени выходного файла при помощи модификатора 'p%03'
scanimage --batch=p%03d.pdf
p001.pdf
# Форматирование имени выходного файла при помощи модификатора '%9d'
scanimage --batch=%9d.pdf
' 1.pdf'
# Форматирование имени выходного файла при помощи модификатора '%-9d'
scanimage --batch=%-9d.pdf
1 .pdf
--batch-start=start
Выбор номера страницы, с которой будет начинаться нумерация имени файла. Если значение не задано, счетчик начинает с "1". Это значение (numbering from 2) можно также увидеть в стандартном выводе команды scanimage
Output format is not set, using pnm as a default.
Scanning infinity pages, incrementing by 1, numbering from 2
Scanning page 2
Примеры:
# Сканирование одного листа с АПД
scanimage --batch=%d.pdf --batch-start=2
2.pdf
--batch-count=count
Указание количества страниц для сканирования. Если значение не задано, scanimage будет продолжать сканировать, пока устройство не вернется в состояние, отличное от "ОК". Не все сканирующие устройства с АПД сигнализируют о пустом лотке АПД. Именно для этих случаев и предназначен этот параметр. Например:
scanimage --format=pdf --batch=scan_dp%d.pdf --batch-count=2 --source=DP
Scanning 2 pages, incrementing by 1, numbering from 1
Scanning page 1
scanimage: sane_start: Document feeder out of documents
Batch terminated, 0 pages scanned
--batch-increment=increment
Устанавливает числовое значение, на которое увеличивается число в имени файла. Обычно это используется при сканировании двусторонних документов с помощью одностороннего устройства подачи документов. Параметр --batch-double - специальная команда, предназначенная для этого.
--batch-double
Автоматическое увеличение числового значения в имени файла на 2. Равносильно --batch-increment=2
Это значение (incrementing by 2) можно также увидеть в стандартном выводе команды scanimage:
u@alse-174-sane:~$ scanimage --format=tiff --batch=scan%d.tiff --batch-double --source='Automatic Document Feeder'
Scanning infinity pages, incrementing by 2, numbering from 1
Scanning page 1
sane_pantum6500_start: dev->doc_source = 200, scanning = 0, reading = 0
Scanned page 1. (scanner status = 5)
Scanning page 3
sane_pantum6500_start: dev->doc_source = 200, scanning = 1, reading = 1
Scanned page 3. (scanner status = 5)
Scanning page 5
Scanned page 5. (scanner status = 5)
Scanning page 7
scanimage: sane_start: Document feeder out of documents
Batch terminated, 3 pages scanned
ls
scan1.tiff scan3.tiff scan5.tiff
--batch-prompt
Запрос на продолжение сканирования от пользователя после сканирования страницы. Может быть использовано при сканировании нескольких страниц на устройстве без АПД. Например:
scanimage --format=pdf --batch=scan%d.pdf -p --batch-prompt
Scanning infinity pages, incrementing by 1, numbering from 1
Place document no. 1 on the scanner.
Press <RETURN> to continue.
Press Ctrl + D to terminate.
Многостраничное сканирование
Для сканирования многостраничных документов очевидно следует передавать в параметры источника бумаги значение source и формат имени создаваемых файлов через batch. Каждый бэкенд именует его по разному. Это может быть как ADF, так и "Automatic Document Feeder". Например:
scanimage --source 'Automatic Document Feeder' --format tiff --batch=scan%04d.tiff -p --resolution 150
Если не задать формат создаваемых файлов, а просто указать единый выходной файл, то будет сохранена только одна отсканированная копия. Другие страницы просто пройдут через АПД без сканирования.
scanimage --source 'Automatic Document Feeder' --format tiff -p --resolution 150 > scan.tiff
Но можно и сразу положить все копии в один файл, scanimage поддерживает сохранение в pdf
scanimage --source 'Automatic Document Feeder' --format pdf --batch=scan%04d.pdf -p --resolution 150
Обработка копий
Для обработки используется утилита convert с сумасшедшим функционалом. Например, конвертирование созданных файлов нескольких tiff-файлов в один pdf
convert -adjoin *.tiff 1.pdf
scanimage и convert можно комбинировать и собирать конструкции вроде
scanimage --source 'Automatic Document Feeder' --format tiff --batch=scan%04d.tiff -p --resolution 150 && convert -adjoin *.tiff 1.pdf && rm *.tiff
для объединения нескольких копий в одну и удаление оригиналов.
Внимание!
Для возможности конвертирования в pdf, необходимо выполнить установку и настройку imagemagick.
sudo apt install imagemagick -y
Внести изменения в /etc/ImageMagick-6/policy.xml, изменив
<policy domain="coder" rights="none" pattern="PDF" />
на
<policy domain="coder" rights="read | write" pattern="PDF" />
Псевдонимы (aliases)
Использование псевдонимов - "изящное" решение частой проблемы, когда переподключение локального устройства или перезагрузка компьютера приводит к изменению имени, что имя устройства, с которым работали фронтенды (fly-scan, naps2, simple-scan) изменяется. Вследствие чего пользователь сталкивается с ошибкой недоступности устройства. Единственным способом решить проблему - выполнить повторный поиск устройства. Разработчики SANE заложили на этот случай воpможность использовать костыль в виде обращения к устройству через псевдоним, указанный в файле /etc/sane.d/dll.aliases и скрипта для udev-правила, который назначит этому псевдониму актуальное имя. Такой подход избавит от проблем с "Избранными" локальными устройствами, каждый раз получающих различные значения DeviceNumber после перезагрузки компьютера.
Настройка несложна. Ниже пример скрипта для устройства Pantum 5100ADW, использующий бэкенд pantum6500, которое является единственным подключенным к компьютеру
/opt/pantum5100adw.sh
#!/bin/bash
MODEL="Pantum BM5100 ADW"
SANEBACKEND=pantum6500
PID=232b
BUS=$(lsusb | grep $PID | awk '{ print $2}')
NUM=$(lsusb | grep $PID | awk '{ print $4}' | sed 's/.$//')
DEVICE=$SANEBACKEND:libusb:$BUS:$NUM
echo "alias \"$MODEL\" $DEVICE" > /etc/sane.d/dll.aliases
Необходимо заполнить переменные MODEL, SANEBACKEND, PID
Сделать скрипт исполняемым
sudo chmod +x /opt/pantum5100adw.sh
Создать udev-правило /etc/udev/rules.d/61-pantum-alias.rules, которое будет идти следом за 60-pantum_mfp.rules и выполнять скрипт RUN+="/opt/pantum5100adw.sh
/etc/udev/rules.d/61-pantum-alias.rules
SUBSYSTEMS=="usb",ATTRS{idVendor}=="232b",ATTRS{idProduct}=="2732",RUN+="/opt/pantum5100adw.sh"
Для применения udev-правила достаточно перезагрузить устройство, или выполнить
sudo udevadm trigger
Проверить успешность выполнения правила можно, взглянув на /etc/sane.d/dll.aliases,
/etc/sane.d/dll.aliases
alias Pantum BM5100 ADW pantum6500:libusb:001:009
файл должен содержать актуальный libusb-путь к устройству. Отныне фронтенд будет работать с псевдонимом (alias) устройства.
scanimage -L
device `PantumMB5100ADW' is a Pantum BM5100ADW series (libusb:001:009)
Аналогичным образом это применимо и к сетевым устройствам. Псевдоним поможет хоть каким-то образом идентифицировать одинаковые модели устройств. Но, к примеру, NAPS2 пошёл своим путем и к нему не применим механизм alias. Как тут с первой попытки попасть на нужный HP - вопрос. Naps2 следует поработать над DeviceURI бэкенда hpaio.
Добавить устройство очень просто:
Список обнаруженных устройств
scanimage -L
device `hpaio:/net/laserjet_pro_m428-m429?ip=10.177.7.76&queue=false' is a Hewlett-Packard laserjet_pro_m428-m429 all-in-one
device `hpaio:/net/colorlaserjet_mfp_m282-m285?ip=10.177.7.173&queue=false' is a Hewlett-Packard colorlaserjet_mfp_m282-m285 all-in-one
Файл /etc/sane.d/dll.aliases
alias HP428 hpaio:/net/laserjet_pro_m428-m429?ip=10.173.22.3&queue=false
alias HP282 hpaio:/net/colorlaserjet_mfp_m282-m285?ip=10.173.22.7&queue=false
Итоговый результат:
scanimage -L
device `HP428' is a Hewlett-Packard laserjet_pro_m428-m429 all-in-one
device `HP282' is a Hewlett-Packard colorlaserjet_mfp_m282-m285 all-in-one
Стоит заметить, что псевдонимы могут также использоваться с целью скрыть реальное имя устройства в целях безопасности или для точной идентификации пользователем при выборе сетевых устройств. В зависимости от настроек устройства и активных сетевых протоколов (например, Bonjour для escl), имя может быть контринтуитивным для пользователя. Например:
device `airscan:w5:HP LaserJet Pro M428-M429 [4FB2F4] (4)' is a WSD HP LaserJet Pro M428-M429 [4FB2F4] (4) ip=10.0.0.41
device `hpaio:/net/colorlaserjet_mfp_m282-m285?ip=10.0.0.43&queue=false' is a Hewlett-Packard colorlaserjet_mfp_m282-m285 all-in-one
Но и это ещё не все. Помимо возможности скрыть имя устройства, конкретное устройство можно "спрятать" от пользователя не внося изменения в настройки конфигурационных файлов бэкенда. Для этого используется команда hide в том же файле /etc/sane.d/dll.aliases. Пример, с сокрытием устройства, для которого назначен псевдоним:
alias Pantum BM5100 ADW pantum6500:libusb:001:009
hide pantum6500:libusb:001:009
В результате поиска при помощи scanimage -L, список будет пуст.
Внимание!
Формат использования hide в /etc/sane.d/dll.aliases чуть отличен от alias. Передавать команде следует имя устройства, но не псевдоним. Это накладывает некие ограничения на гибкость решения, так как требуется править начальный исполняемый скрипт /opt/pantum5100adw.sh для получения актуального имени.
#!/bin/bash
MODEL="Pantum BM5100 ADW"
SANEBACKEND=pantum6500
PID=232b
BUS=$(lsusb | grep $PID | awk '{ print $2}')
NUM=$(lsusb | grep $PID | awk '{ print $4}' | sed 's/.$//')
DEVICE=$SANEBACKEND:libusb:$BUS:$NUM
echo "hide $DEVICE" > /etc/sane.d/dll.aliases
Тестовый бэкенд (test)
SANE заложил возможность использование виртуального устройства через бэкенд test [40]. По-умолчанию, строка с названием бэкенда test закомментирована в /etc/sane.d/dll.conf. Виртуальное устройство именуется аналогично - test. Пример тестового сканирования тестового бэкенда (да, вот такой каламбур):
scanimage -d test -T
Output format is not set, using pnm as a default.
scanimage: scanning image of size 157x196 pixels at 8 bits/pixel
scanimage: acquiring gray frame, 8 bits/sample
scanimage: reading one scanline, 157 bytes... PASS
scanimage: reading one byte... PASS
scanimage: stepped read, 2 bytes... PASS
scanimage: stepped read, 4 bytes... PASS
scanimage: stepped read, 8 bytes... PASS
scanimage: stepped read, 16 bytes... PASS
scanimage: stepped read, 32 bytes... PASS
scanimage: stepped read, 64 bytes... PASS
scanimage: stepped read, 128 bytes... PASS
scanimage: stepped read, 256 bytes... PASS
scanimage: stepped read, 255 bytes... PASS
scanimage: stepped read, 127 bytes... PASS
scanimage: stepped read, 63 bytes... PASS
scanimage: stepped read, 31 bytes... PASS
scanimage: stepped read, 15 bytes... PASS
scanimage: stepped read, 7 bytes... PASS
scanimage: stepped read, 3 bytes... PASS
Использование виртуального устройства будет полезным для тестирования графических программ с максимально широкими возможностями драйвера test. В основном, просто помогает запустить фронтенд (например fly-scan), чтобы посмотреть функционал графического приложения.
Виртуальное устройство (pnm)
Довольно экзотический способ тестирования фронтенда для обработки изображений с использованием бэкенда pnm. Библиотека /usr/lib/x86_64-linux-gnu/sane/libsane-pnm.so.1.1.1 входит в состав libsane1, для его включения необходимо только добавить строку pnm в конфигурационный файл /etc/sane.d/dll.conf. В результате, список устройств пополнится pnm:0 и pnm:1
scanimage -L
device `pnm:0' is a Noname PNM file reader virtual device
device `pnm:1' is a Noname PNM file reader virtual device
device `pantum6500:libusb:001:004' is a Pantum BM5100ADW series (libusb:001:004)
ipp-usb (ipp-usb)
Не удастся обойти стороной и пакет ipp-usb. Хоть он и не является частью SANE, с его наличием в ОС связана одна из распространенных проблем с обнаружением локального устройства. Пакет ставится как зависимость sane-airscan (поведение в 1.7.6.Х будет изменено, пакет будет отмечен как предлагаемый Suggests для sane-airscan_0.99.19-1~bpo10+1+ci1), и служба ipp-usb.service благополучно запустится самостоятельно после подключения устройства к USB.
Без лишних уведомлений для пользователя. В dmesg, с некоторой задержкой после подключения может проскочить сообщение о выгрузке модуля usblp. Но с настройками по умолчанию в конфигурационном файле /etc/ipp-usb/ipp-usb.conf указано использование loopback интерфейса, и устройство больше не будет доступно. Ни локальное, ни сетевое. Не доступно как с хоста, так и с другого сетевого клиента.
Как узнать, что локальное устройство занято запущенной службой ipp-usb.service?
Разумеется, присутствие самого пакета ipp-usb
dpkg -l ipp-usb
ii ipp-usb 0.9.17-3+b2 amd64 Daemon for IPP over USB printer support
и запущенная одноименная служба,
sudo systemctl status ipp-usb
● ipp-usb.service - Daemon for IPP over USB printer support
Loaded: loaded (/lib/systemd/system/ipp-usb.service; static; vendor preset: enabled)
Active: active (running) since Tue 2024-05-07 21:45:24 MSK; 23min ago
Docs: man:ipp-usb(8)
Main PID: 19633 (ipp-usb)
Tasks: 11 (limit: 2220)
Memory: 2.8M
CPU: 126ms
CGroup: /system.slice/ipp-usb.service
└─19633 /sbin/ipp-usb udev
мая 07 21:45:24 alse176 systemd[1]: Started Daemon for IPP over USB printer support.
или вывод команды ipp-usb,
sudo ipp-usb check
IPP over USB devices:
Num Device Vndr:Prod Model
1. Bus 004 Device 004 232b:2732 "Pantum BM5100ADW series"
или, мой самый любимый, - наличие файлов в директории с отладочной информацией /var/log/ipp-usb/<device_name>.log
При всем этом sane-find-scanner найдет устройство. Ранее мы говорили об этом для определения сканера, он проверяет значения bInterfaceClass=255 (Vendor Specific Interface) интерфейсов.
Как это выглядит со стороны фронтенда. scanimage покажет, что устройство (интерфейс) предположительно занято модулем scanner или usblp.
SANE_DEBUG_SANEI_USB=4 scanimage -L
[20:17:56.207492] [sanei_usb] device name: libusb:004:004-BM5100ADW series
[20:17:56.207910] [sanei_usb] com_pantum_sanei_usb_open: libusb complained: Resource busy
[20:17:56.208012] [sanei_usb] Maybe the kernel scanner driver or usblp claims the interface? Ignoring this error...
[20:17:56.208147] [sanei_usb] com_pantum_sanei_usb_open: libusb complained: Resource busy
[20:17:56.208223] [sanei_usb] Maybe the kernel scanner driver claims the scanner's interface?
[20:17:57.208731] [sanei_usb] com_pantum_sanei_usb_open: libusb complained: Resource busy
[20:17:57.208848] [sanei_usb] Maybe the kernel scanner driver or usblp claims the interface? Ignoring this error...
[20:17:57.208974] [sanei_usb] com_pantum_sanei_usb_open: libusb complained: Resource busy
[20:17:57.209062] [sanei_usb] Maybe the kernel scanner driver claims the scanner's interface?
[20:17:58.209563] [sanei_usb] com_pantum_sanei_usb_open: libusb complained: Resource busy
[20:17:58.209680] [sanei_usb] Maybe the kernel scanner driver or usblp claims the interface? Ignoring this error...
[20:17:58.209829] [sanei_usb] com_pantum_sanei_usb_open: libusb complained: Resource busy
[20:17:58.209919] [sanei_usb] Maybe the kernel scanner driver claims the scanner's interface?
Чуть иначе для сравнения выглядит вывод отладочной информации от драйвера kyocera_wc3_usb
SANE_DEBUG_KYOCERA_WC3_USB=255 scanimage -L
[kyocera_debug] Setting debug level of kyocera_wc3_usb to 255.
[kyocera_wc3_usb] >>sane_init
[kyocera_wc3_usb] sane_init() : Kyocera backend (build 1), version != null, authorize != null
[kyocera_wc3_usb] <<sane_init
[kyocera_wc3_usb] >>sane_get_devices
[kyocera_wc3_usb] sane_get_devices() : start reading config file kyocera_wc3_usb.conf
<...>
[kyocera_wc3_usb] attach_one_usb()
[kyocera_wc3_usb] attach_one()
[kyocera_wc3_usb] connect_scanner() : INFO : connecting usb scanner device libusb:002:002
[kyocera_wc3_usb] attach_one() : ERROR : failed to open scanner with device name libusb:002:002
[kyocera_wc3_usb] sane_get_devices() : usb 0x0482 0x0ca7
В обоих случаях libusb (более верно будет сказать бэкенд через libusb) не может обменяться данными с устройством. Интерфейс(ы) кем-то заняты. После неудачных попыток обращения бэкенда dmesg выведет 3 одинаковых сообщения (по одному на каждый интерфейс) от usbfs о том, что интерфейс занят usbfs.
dmesg --level=warn
Перечисленные ниже события имеют тип Warning. Вывести все события этого уровня можно через dmesg --level=warn
[42294.012641] usb 1-1: usbfs: interface 0 claimed by usbfs while 'scanimage' sets config #1
[42295.013138] usb 1-1: usbfs: interface 0 claimed by usbfs while 'scanimage' sets config #1
[42296.013534] usb 1-1: usbfs: interface 0 claimed by usbfs while 'scanimage' sets config #1
в этом можно убедиться, просмотрев вывод
sudo cat /sys/kernel/debug/usb/devices
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=232b ProdID=2732 Rev= 1.00
S: Manufacturer=Pantum
S: Product=BM5100ADW series
S: SerialNumber=CK1A046238
C:* #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr= 2mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=07(print) Sub=01 Prot=02 Driver=usbfs
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=1250us
I:* If#= 0 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=04 Driver=usbfs
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=usbfs
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=1250us
E: Ad=84(I) Atr=03(Int.) MxPS= 12 Ivl=64ms
I:* If#= 1 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=04 Driver=usbfs
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=usbfs
E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=04 Driver=usbfs
E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Все альтернативные интерфейсы (If#= 0-2 Alt= 1) стали активными (сравните с выводом в начале), и для них уже загружен модуль usbfs. Интерфейсы заняты тем же libusb, функцией libusb_claim_interface() [41], но породил этот процесс ipp-usb
sudo lsof /dev/bus/usb/001/003
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ipp-usb 19633 root 12u CHR 189,2 0t0 468 /dev/bus/usb/001/003
Вот для сравнения вывод usb-devices при отключенной службе ipp-usb
ipp-usb disable
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=232b ProdID=2732 Rev=01.00
S: Manufacturer=Pantum
S: Product=BM5100ADW series
S: SerialNumber=CK1A046238
C: #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr=2mA
I: If#=0x0 Alt= 0 #EPs= 2 Cls=07(print) Sub=01 Prot=02 Driver=usblp
I: If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I: If#=0x2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
и активной
ipp-usb enabled
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=232b ProdID=2732 Rev=01.00
S: Manufacturer=Pantum
S: Product=BM5100ADW series
S: SerialNumber=CK1A046238
C: #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr=2mA
I: If#=0x0 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=04 Driver=usbfs
I: If#=0x1 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=04 Driver=usbfs
I: If#=0x2 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=04 Driver=usbfs
Включенная отладка usbfs_snoop (см. раздел Диагностика) будет содержать событие об открытом процессом ipp-usb интерфейсе usb 1-1
dmesg
[296556.897166] usb 1-1: new high-speed USB device number 6 using ehci-pci
[296557.350512] usb 1-1: New USB device found, idVendor=232b, idProduct=2732, bcdDevice= 1.00
[296557.350536] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[296557.350551] usb 1-1: Product: BM5100ADW series
[296557.350562] usb 1-1: Manufacturer: Pantum
[296557.350573] usb 1-1: SerialNumber: CK1A046238
[296557.467506] usblp 1-1:1.0: usblp0: USB Bidirectional printer dev 6 if 0 alt 0 proto 2 vid 0x232B pid 0x2732
[296557.703523] usb 1-1: opened by process 23010: ipp-usb
Тут же можно зафиксировать периодический обмен данными устройства с хостом
Отладочная информация
<...>
[296657.745671] data: 0e 03 50 00 61 00 6e 00 74 00 75 00 6d 00 ..P.a.n.t.u.m.
[296657.745756] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.745768] usb 1-1: reap 00007ef698000fc0
[296657.745801] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.745926] usb 1-1: usbdev_do_ioctl: SUBMITURB
[296657.745938] usb 1-1: control urb: bRequestType=80 bRequest=06 wValue=0300 wIndex=0000 wLength=0004
[296657.745980] usb 1-1: userurb 00007ef698000c60, ep0 ctrl-in, length 4
[296657.768639] usb 1-1: urb complete
[296657.768651] usb 1-1: userurb 00007ef698000c60, ep0 ctrl-in, actual_length 4 status 0
[296657.768670] data: 04 03 09 04 ....
[296657.768758] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.768770] usb 1-1: reap 00007ef698000c60
[296657.768803] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.768919] usb 1-1: usbdev_do_ioctl: SUBMITURB
[296657.768932] usb 1-1: control urb: bRequestType=80 bRequest=06 wValue=0302 wIndex=0409 wLength=00ff
[296657.768975] usb 1-1: userurb 00007ef698000fc0, ep0 ctrl-in, length 255
[296657.792433] usb 1-1: urb complete
[296657.792445] usb 1-1: userurb 00007ef698000fc0, ep0 ctrl-in, actual_length 34 status 0
[296657.792464] data: 22 03 42 00 4d 00 35 00 31 00 30 00 30 00 41 00 44 00 57 00 20 00 73 00 65 00 72 00 69 00 65 00 ".B.M.5.1.0.0.A.D.W. .s.e.r.i.e.
[296657.792478] data: 73 00 s.
[296657.792565] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.792577] usb 1-1: reap 00007ef698000fc0
[296657.792611] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.792732] usb 1-1: usbdev_do_ioctl: SUBMITURB
[296657.792745] usb 1-1: control urb: bRequestType=80 bRequest=06 wValue=0300 wIndex=0000 wLength=0004
[296657.792786] usb 1-1: userurb 00007ef698000c60, ep0 ctrl-in, length 4
[296657.815483] usb 1-1: urb complete
[296657.815496] usb 1-1: userurb 00007ef698000c60, ep0 ctrl-in, actual_length 4 status 0
[296657.815515] data: 04 03 09 04 ....
[296657.815608] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.815620] usb 1-1: reap 00007ef698000c60
[296657.815652] usb 1-1: usbdev_do_ioctl: REAPURBNDELAY
[296657.815767] usb 1-1: usbdev_do_ioctl: SUBMITURB
[296657.815780] usb 1-1: control urb: bRequestType=80 bRequest=06 wValue=0303 wIndex=0409 wLength=00ff
[296657.815822] usb 1-1: userurb 00007ef698000fc0, ep0 ctrl-in, length 255
[296657.836933] usb 1-1: urb complete
[296657.836945] usb 1-1: userurb 00007ef698000fc0, ep0 ctrl-in, actual_length 22 status 0
[296657.836964] data: 16 03 43 00 4b 00 31 00 41 00 30 00 34 00 36 00 32 00 33 00 38 00 ..C.K.1.A.0.4.6.2.3.8.
<...>
Чтобы устройство стало доступно по сети, потребуется поменять значение interface с loopback на all (указать конкретный интерфейс, например eth0 не удастся, служба не запустится) в конфигурационном файле /etc/ipp-usb/ipp-usb.conf
/etc/ipp-usb/ipp-usb.conf
interface = all
тут же можно указать диапазон портов, поддержку ipv6 и уровень логирования.
В целом, концепция работы описана на странице [42] проекта. Огромным преимуществом ipp-usb является отсутствие необходимости устанавливать драйвер. Также, ipp-usb поможет с поддержкой локального устройства на других аппаратных платформах (речь в первую очередь идёт об OpenWRT) о которых не позаботился вендор. В жертву удобству идут ограничения драйвера escl, по сравнению с локальным бэкендом. Для сравнения:
escl
All options specific to device `escl:http://10.0.0.12:60000':
Scan mode:
--mode Color|Gray|Lineart [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--resolution 75|150|300|600dpi [75]
Sets the resolution of the scanned image.
--source Flatbed|ADF|ADF Duplex [Flatbed]
Selects the scan source (such as a document-feeder).
Geometry:
-l 0..205.063mm [0]
Top-left x position of scan area.
-t 0..286.173mm [0]
Top-left y position of scan area.
-x 10.8373..215.9mm [215.9]
Width of scan-area.
-y 10.8373..297.011mm [297.011]
Height of scan-area.
Enhancement:
--preview[=(yes|no)] [no]
Request a preview-quality scan.
--preview-in-gray[=(yes|no)] [no]
Request that all previews are done in monochrome mode. On a
three-pass scanner this cuts down the number of passes to one and on a
one-pass scanner, it reduces the memory requirements and scan-time of
the preview.
--brightness 32766..8158832 [inactive]
Controls the brightness of the acquired image.
--contrast 32766..8158832 [inactive]
Controls the contrast of the acquired image.
--sharpen 32766..8158832 [inactive]
Set sharpen value.
--threshold 32766..8158832 [inactive]
Select minimum-brightness to get a white point
pantum6500. Как видим, оригинальный драйвер имеет возможность сканировать в более высоком разрешении (1200dpi)
pantum6500
All options specific to device `pantum6500:libusb:004:005':
Standard:
--preview[=(yes|no)] [no]
Request a preview-quality scan.
--resolution 75|150|300|600|1200dpi [300]
Sets the resolution of the scanned image.
--mode Lineart|Gray|Color [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--threshold 1..255 [inactive]
Select minimum-brightness to get a white point
--source Flatbed|Automatic Document Feeder|Automatic Document Feeder (Duplex) [Flatbed]
Selects the scan source (such as a document-feeder).
--geometry 稿台|A4|A5|B5|Letter|Full size [A4]
Scan area and media size options
-l 0..216mm (in steps of 1) [0]
Top-left x position of scan area.
-t 0..297mm (in steps of 1) [0]
Top-left y position of scan area.
-x 0..216mm (in steps of 1) [216]
Width of scan-area.
-y 0..297mm (in steps of 1) [297]
Height of scan-area.
Этих и других недостатков лишен сетевой бэкенд net. Об этом чуть ниже в главе saned.
Как решить проблему с монопольным доступом к устройству службой ipp-usb? В большинстве случаев - просто удалить пакет. Или остановить, а затем отключить службу. Если все же необходимость в ipp-usb сохраняется, скажем только для конкретного USB-устройства, неугодное(ых) можно добавить в /usr/share/ipp-usb/quirks/blacklist.conf.
/usr/share/ipp-usb/quirks/blacklist.conf
[Pantum BM5100ADW series]
blacklist = true
и после перезапуска службы, локальное устройство будет снова доступно.
Более детально о синтаксисе blacklist можно узнать из man ipp-usb (раздел Quirks)
saned (sane-utils)
Служба для предоставления доступа к локально подключенному устройству по сети через бэкенд net [43]. Порядок настройки описан в статье Saned. Подключение удаленного сканера [44].
Помимо традиционных сценариев использования, скажем, поделиться локальным устройством по сети, служба также может быть использована и для сетевых устройств, для которых сетевые бэкенды имеют ограниченный функционал. Главная "киллер-фича" бэкенда - использование по сети всего функционала оригинального локального бэкенда. Для сравнения, вариант ipp-usb с бэкендом escl
escl
All options specific to device `escl:http://10.0.0.12:60000':
Scan mode:
--mode Color|Gray|Lineart [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--resolution 75|150|300|600dpi [75]
Sets the resolution of the scanned image.
--source Flatbed|ADF|ADF Duplex [Flatbed]
Selects the scan source (such as a document-feeder).
Geometry:
-l 0..205.063mm [0]
Top-left x position of scan area.
-t 0..286.173mm [0]
Top-left y position of scan area.
-x 10.8373..215.9mm [215.9]
Width of scan-area.
-y 10.8373..297.011mm [297.011]
Height of scan-area.
Enhancement:
--preview[=(yes|no)] [no]
Request a preview-quality scan.
--preview-in-gray[=(yes|no)] [no]
Request that all previews are done in monochrome mode. On a
three-pass scanner this cuts down the number of passes to one and on a
one-pass scanner, it reduces the memory requirements and scan-time of
the preview.
--brightness 32766..8158832 [inactive]
Controls the brightness of the acquired image.
--contrast 32766..8158832 [inactive]
Controls the contrast of the acquired image.
--sharpen 32766..8158832 [inactive]
Set sharpen value.
--threshold 32766..8158832 [inactive]
Select minimum-brightness to get a white point
и с сетевым бэкендом net
scanimage -d 'net:10.0.0.12:pantum6500:libusb:004:005' -T
All options specific to device `net:10.0.0.12:pantum6500:libusb:004:005':
Standard:
--preview[=(yes|no)] [no]
Request a preview-quality scan.
--resolution 75|150|300|600|1200dpi [300]
Sets the resolution of the scanned image.
--mode Lineart|Gray|Color [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--threshold 1..255 [inactive]
Select minimum-brightness to get a white point
--source Flatbed|Automatic Document Feeder|Automatic Document Feeder (Duplex) [Flatbed]
Selects the scan source (such as a document-feeder).
--geometry 稿台|A4|A5|B5|Letter|Full size [A4]
Scan area and media size options
-l 0..216mm (in steps of 1) [0]
Top-left x position of scan area.
-t 0..297mm (in steps of 1) [0]
Top-left y position of scan area.
-x 0..216mm (in steps of 1) [216]
Width of scan-area.
-y 0..297mm (in steps of 1) [297]
Height of scan-area.
Ещё одним преимуществом является то, что запущенный saned позволяет пользоваться устройством на рабочем месте, к которому устройство подключено локально. Устройство не блокируется как с ipp-usb.
scanimage x32 (sane-utils)
Имея дело со сканирующими устройствами, часто приходится сталкиваться с ситуацией, когда устройство ещё работает (это не редко), а драйверов к нему уже нет (а вот это уже часто). Да, раньше умели делать оргтехнику. Современный рынок производитель не считает нужным почтить память снятого с производства устройства, выложив исходный код драйвера для использования сообществом. В качестве таких артефактов (и это в целом, лучше чем ничего) можно найти пакеты драйверов для i386 архитектуры. Но как ими пользоваться в 64-разрядной ОС? Простой установкой 32-битных библиотек ia32-libs тут не обойтись. Потребуется использовать фронтенд для работы с этими библиотеками.
Попробуем собрать 32 битную версию scanimage для поддержки консольного сканирования на стареньком Xerox 3100. Посмотрите на этого красавца, "Где мой 2008 год...")
Загружаем любимый 32-битный дистрибутив в Live-режиме и выполняем сборку backends-1.3.1
apt install autopoint gettext automake autotools-dev autoconf libtool patch autoconf-archive pkg-config libusb-dev libusb-dev build-essential libsane-dev libavahi-client-dev libavahi-glib-dev -y
wget https://gitlab.com/sane-project/backends/-/archive/1.3.1/backends-1.3.1.zip
unzip backends-1.3.1.zip
cd backends-1.3.1
./autogen.sh
./configure --disable-dependency-tracking
make
Сборка
Получить полную справку по возможным параметрам сборки
./configure --help
Перемещаем исполняемый файл /usr/local/bin/scanimage на 64 разрядную ОС. Выполняем установку библиотек ia32-libs
sudo apt install ia32-libs
И выполняем тестовый запуск с отладочной информацией SANE_DEBUG_DLL=255 ./scanimage
[10:02:13.367457] [sanei_debug] Setting debug level of dll to 255.
[10:02:13.368482] [dll] sane_init: SANE dll backend version 1.0.13 from sane-backends 1.1.1-debian
[10:02:13.369346] [dll] sane_init/read_dlld: attempting to open directory `./dll.d'
[10:02:13.370720] [dll] sane_init/read_dlld: attempting to open directory `/etc/sane.d/dll.d'
[10:02:13.371457] [dll] sane_init/read_dlld: using config directory `/etc/sane.d/dll.d'
[10:02:13.373575] [dll] sane_init/read_dlld: considering /etc/sane.d/dll.d/airscan
[10:02:13.374197] [dll] sane_init/read_config: reading dll.d/airscan
[10:02:13.374742] [dll] add_backend: adding backend `airscan'
[10:02:13.375260] [dll] sane_init/read_dlld: done.
[10:02:13.375792] [dll] sane_init/read_config: reading dll.conf
[10:02:13.376303] [dll] add_backend: adding backend `net'
[10:02:13.376778] [dll] add_backend: adding backend `abaton'
<...>
[10:02:13.405631] [dll] add_backend: adding backend `kyocera'
[10:02:13.406028] [dll] add_backend: adding backend `kyocera_gdi_a3'
[10:02:13.406199] [dll] add_backend: adding backend `kyocera_wc3'
[10:02:13.406559] [dll] add_backend: adding backend `kyocera_wc3_usb'
Output format is not set, using pnm as a default.
[10:02:13.408282] [dll] sane_get_devices
[10:02:13.408675] [dll] load: searching backend `kyocera_wc3_usb' in `/usr/lib/i386-linux-gnu/sane:/usr/lib/sane:/usr/lib64/sane'
[10:02:13.408812] [dll] load: trying to load `/usr/lib/i386-linux-gnu/sane/libsane-kyocera_wc3_usb.so.1'
[10:02:13.409279] [dll] load: couldn't open `/usr/lib/i386-linux-gnu/sane/libsane-kyocera_wc3_usb.so.1' (No such file or directory)
[10:02:13.409656] [dll] load: trying to load `/usr/lib/sane/libsane-kyocera_wc3_usb.so.1'
[10:02:13.409855] [dll] load: dlopen()ing `/usr/lib/sane/libsane-kyocera_wc3_usb.so.1'
[10:02:13.412141] [dll] load: dlopen() failed (/usr/lib/sane/libsane-kyocera_wc3_usb.so.1: wrong ELF class: ELFCLASS64)
[10:02:13.412564] [dll] load: searching backend `kyocera_wc3' in `/usr/lib/i386-linux-gnu/sane:/usr/lib/sane:/usr/lib64/sane'
[10:02:13.412996] [dll] load: trying to load `/usr/lib/i386-linux-gnu/sane/libsane-kyocera_wc3.so.1'
[10:02:13.413171] [dll] load: couldn't open `/usr/lib/i386-linux-gnu/sane/libsane-kyocera_wc3.so.1' (No such file or directory)
[10:02:13.413558] [dll] load: trying to load `/usr/lib/sane/libsane-kyocera_wc3.so.1'
[10:02:13.413748] [dll] load: dlopen()ing `/usr/lib/sane/libsane-kyocera_wc3.so.1'
[10:02:13.414203] [dll] load: dlopen() failed (/usr/lib/sane/libsane-kyocera_wc3.so.1: wrong ELF class: ELFCLASS64)
<...>
Замечательно, в этом случае, ошибка
[10:02:13.414203] [dll] load: dlopen() failed (/usr/lib/sane/libsane-kyocera_wc3.so.1: wrong ELF class: ELFCLASS64)
сигнализирует о корректной работе scanimage, ему необходимы 32-битные версии библиотек бэкенда. Они же потребуются для установки драйвера. Тестовое сканирование выполнять с указанием абсолютного пути до исполняемого файла. Для удобства и контроля выполнения, его можно перенести и заботливо переименовать в /usr/bin/scanimage32.
/usr/bin/scanimage --format=jpg -d XeroxPhaser3100:usb:001:002 > /image.jpg
Таким образом, в системе по умолчанию будет по-прежнему использоваться рабочее 64-битное окружение с его бэкендами и графическими фронтендами. Но в случае необходимости, существует возможность использовать 32-битные фронтенды.
Заключение
Если вам посчастливилось добраться до этой части, внимательно изучив все три материала (полагаю, это возможно в случае, если пришлось столкнуться с проблемами при настройке сканеров), то картина убогого устройства SANE у вас в голове сформировалась.
Из года в год кодовая база пополняется поддержкой новых устройств, расширяется список протестированных, решаются проблемы текущих устройств. Но основная механика остается неизменна. А что в этом плохого? Ну как:
legacy устройства (да, я про SCSI) тормозят простой запуск, затрачивая время на инициализацию и поиск совместимых устройств.
алгоритм поиска устройств не эффективен. Зачем тратить время на инициализацию всех бэкендов, когда на момент запуска, уникальный идентификатор idVendor и idProduct уже известен и можно ограничиться запуском только нужного бэкенда. Да, придется прошерстить тысячу строк, но это всё равно быстрее.
отсутствие механизма управления атрибутами устройства для облегчения идентификации и инвентаризации. Например: "Расположение", "Адрес", "Кабинет". Да что говорить, имя устройства (DeviceURI) не поменять!
отсутствие механизма управления свойств устройства для тех же целей при поиске подходящего под твои задачи устройства. Например: "Цветное сканирование", "Поддержка сканирования А3", "Двусторонний АПД" и т.п.
нет единого пространства управления устройствами. Фронтенд сканирования не в счет, он пользуется готовым именем и работает с тем, что нашел. Частично это решается проприетарным ПО вендора, но понятное дело, список поддерживаемых устройств этим ПО ограничен производителем.
Очевидно, проект не разрабатывается как корпоративное масштабируемое решение и предназначен в первую очередь для пользователей, но не для доменных структур. Поэтому далее продолжать нет смысла, можете сами придумать, взяв в пример функционал принт-сервера.
Появление подобного программного комплекса - вопрос времени.