Уведомления

Группа в Telegram: @pythonsu

#1 Июль 18, 2017 18:39:33

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Python 3.4 Windows 7 32bit
Хочу написать простую программу для сканирования.Итоговым форматом должен бытьь pdf, причём, и многостраничный тоже.

Из всех имеющихся (точнее тех, что я нашёл) пакетов, у меня заработал только pytwain 2.0. И то, пришлось в тексте его программы поправить строчку импорта: заменить import Image на from PIL import Image.

Сумел сделать посредством этого модуля только прямое сканирование в файл. result = twain.acquire(filename, dpi = 200 и т.д.). Моего знания английского не хватает, чтобы врубиться в инструкции на домашнем сайте этого модуля. Не могу понять что нужно подсовывать в качестве параметров классу SourceManager. В интернетах пишут, что надо передать ноль. Но с нулём у меня не работает. С единицей работает чего-то там. Что этот ноль с единицей значат вообще?

Мне же, в итоге, нужно загрузить несколько изображений в память, затем их превратить в многостраничный pdf. Естественно, нужны и установки настроек типа dpi, цветность, размер сканируемой области, формат получаемого изображения и т.д.
Может кто-то использовал сей модуль и может поделиться кодом-примером? Или знает и подскажет какой-то другой модуль для работы со сканером?

Офлайн

#2 Июль 18, 2017 20:09:09

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Эээ, а чем этот pdf будет отличаться от обычного изображения?



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Июль 19, 2017 06:11:01

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Только тем, что это набор изображений запихнутых в многостраничный pdf.
И меня волнует не само создание pdf (это я как-нибудь сделаю, надеюсь), меня волнует как мне вообще отсканировать несколько изображений в память, чтобы что-то потом с ними я мог сделать.

Офлайн

#4 Июль 19, 2017 09:45:59

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

http://pytwain.readthedocs.io/en/latest/twain.html#module-twain

 class twain.Source(sm, ds_id)[source]
......
An instance of this class can be created by calling SourceManager.open_source()
Инстанс этого класса может быть создан вызовом SourceManager.open_source()
acquire_file(before, after=<function <lambda>>, show_ui=True, modal=False)[source]
Acquires one ore more images as files. Call
получить одно или более изображений как файл .......
.......
acquire_natively(after, before=<function <lambda>>, show_ui=True, modal=False)[source]
Acquires one ore more images in memory.
получить одно или более изображений в память
.......
а вот небольшой пример как сканировать многостраничный документ
https://stackoverflow.com/questions/34924027/how-to-scan-multiple-file-in-twain
только в нем сохраняеться каждая стриничка отдельным файлом.
Дальше экспериментируйте…



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Июль 19, 2017 09:46:32)

Офлайн

#5 Июль 19, 2017 13:42:35

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Пример по ссылке не работает.
Даже в процедуру onTwainEvent перехода не происходит.

Вот такой код работает. Только создаёт он, видимо, никак не сжатый jpg. Файл больно здоровый получается.

 import twain
obj = twain.SourceManager(1)
print ("obj.source_list = ", obj.source_list)
print ("obj.identity    = ", obj.identity)
source = obj.open_source(obj.source_list[0].encode("utf8")) # encode обязателен.
source.RequestAcquire(0, 0)
rv = source.XferImageNatively()
(handle, count) = rv
twain.DIBToBMFile(handle, "jpg.jpg")

Но куда тут запихивать настройки сканирования? Как указать dpi, цветность и т.д?
Почему obj = twain.SourceManager(0) вызывает ошибку?
twain.py“, line 2036, in __init__
raise excSMOpenFailed(”, return code %d" % (dsm_name, rv))
twain.excSMOpenFailed: , return code 1
Если указать (1), то эта команда сработает.
Но для source = obj.open_source(obj.source_list.encode(“utf8”)) обязательно нужно прописать всё это в скобках (это, видимо, выбранный источник сканирования). Пустые скобки, как в ссылке в примере вызывают ошибку тоже.

Отредактировано Pluto (Июль 19, 2017 13:44:11)

Офлайн

#6 Июль 19, 2017 17:53:49

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Pluto
Почему obj = twain.SourceManager(0) вызывает ошибку?
ну шо вам сказать? вы документацию то читали? что там написано?
class twain.SourceManager(parent_window=None, MajorNum=1, MinorNum=0, Language=13, Country=1, Info='', ProductName='TWAIN Python Interface', ProtocolMajor=2, ProtocolMinor=1, SupportedGroups=3, Manufacturer='Kevin Gill', ProductFamily='TWAIN Python Interface', dsm_name=None)

:param parent_window: can contain Tk, Wx or Gtk window object or the windows handle of the main window

тоесть первый аргумент это указатель на ваше главное окно.. что такое 0 который вы пытаетесь туда передать? Попробуйте вообще без аргументов вызвать..

Pluto
Только создаёт он, видимо, никак не сжатый jpg. Файл больно здоровый получается.
А с чего ему создавать сжатй жпег? если DIBToBMFile согласно документации “Convert a DIB (Device Independent Bitmap) to a windows bitmap file format.” что в переводе означает конвертирует DIB в формат windows BMP.

Pluto
Но куда тут запихивать настройки сканирования? Как указать dpi, цветность и т.д?
никуда, я так понимаю автор тулзы оставл это вам. По сути сам модуль довольно “низкоуровневый” и требует от вас все писать рчками.
а twain.acquire по сути пример как его использовать
 def acquire(path,
            ds_name=None,
            dpi=None,
            pixel_type=None,
            bpp=None,
            frame=None,
            parent_window=None,
            show_ui=False,
            dsm_name=None):
    """Acquires single image into file
    :param path: Path where to save image
    :keyword ds_name: name of twain data source, if not provided user will be presented with selection dialog
    :keyword dpi: resolution in dots per inch
    :keyword pixel_type: can be 'bw', 'gray', 'color'
    :keyword bpp: bits per pixel
    :keyword frame: tuple (left, top, right, bottom) scan area in inches
    :keyword parent_window: can be Tk, Wx, Gtk window object or Win32 window handle
    :keyword show_ui: if True source's UI dialog will be presented to user
    Returns a dictionary describing image, or None if scanning was cancelled by user
    """
    if pixel_type:
        pixel_type_map = {'bw': TWPT_BW,
                          'gray': TWPT_GRAY,
                          'color': TWPT_RGB}
        twain_pixel_type = pixel_type_map[pixel_type]
    if not parent_window:
        from tkinter import Tk
        parent_window = Tk()        
    sm = SourceManager(parent_window, dsm_name=dsm_name)
    try:
        sd = sm.open_source(ds_name)
        if not sd:
            return None
        try:
            if pixel_type:
                sd.set_capability(ICAP_PIXELTYPE, TWTY_UINT16, twain_pixel_type)
            sd.set_capability(ICAP_UNITS, TWTY_UINT16, TWUN_INCHES)
            if bpp:
                sd.set_capability(ICAP_BITDEPTH, TWTY_UINT16, bpp)
            if dpi:
                sd.set_capability(ICAP_XRESOLUTION, TWTY_FIX32, dpi)
                sd.set_capability(ICAP_YRESOLUTION, TWTY_FIX32, dpi)
            if frame:
                try:
                    sd.set_image_layout(frame)
                except CheckStatus:
                    pass
        
            res = []
            def before(img_info):
                res.append(img_info)
                return path
            
            def after(more):
                if more:
                    raise CancelAll
        
            try:
                sd.acquire_file(before=before, after=after, show_ui=show_ui)
            except excDSTransferCancelled:
                return None
        finally:
            sd.close()
    finally:
        sm.close()
    return res[0]
тоесть настройки dpi цветности , и тд.. устанавливаються через метод set_capability инстанса класса Source и в итоге дергает acquire_file, чтобы получить картинку в файл.
Вам чтобы считать в память несколько изображений нужно взять за образец twain.acquire допилить где считаете нужным и заменить acquire_file на вызов acquire_natively., В итоге вы должны получить список обьектов в памяти с изображениями и делать с ними что хотите.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Июль 19, 2017 17:57:06)

Офлайн

#7 Июль 20, 2017 05:51:58

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Да вот леший его знает что это за ноль или единица. Ноль был в примерах, которые я находил в Интернетах. С нулём у меня не работает. С единицей работает.
GUI я могу сделать только на PyQt, которая в типах окон в параметрах тут не значится; и попытка подсунуть в качестве parent_window виджет от PyQt приводит к ошибке.

Офлайн

#8 Июль 20, 2017 09:32:30

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Pluto
и попытка подсунуть в качестве parent_window виджет от PyQt приводит к ошибке.
ну в исходниках есть такой кусок
             if hasattr(parent_window, 'winfo_id'):
                # tk window
                self._hwnd = parent_window.winfo_id()
            elif hasattr(parent_window, 'GetHandle'):
                # wx window
                self._hwnd = parent_window.GetHandle()
            elif hasattr(parent_window, 'window') and hasattr(parent_window.window, 'handle'):
                # gtk window
                self._hwnd = parent_window.window.handle
            elif parent_window is None:
                self._hwnd = 0
            else:
                self._hwnd = int(parent_window)
как видно PyQT нет в списке, пробуйте указать или None или получить вендовый хендл на ваше QT-окно, и передать его…



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#9 Июль 20, 2017 10:15:32

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  1  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

 import twain
# получаем список имеющихся источников для сканирования   
sm = twain.SourceManager(1) # некий менеджер в свойствах которого будет этот источник
source_list = sm.source_list # получили список источников
# создаём объект для работы с источником и указываем ему этот самый источник
source = sm.open_source(source_list[0].encode()) # encode() обязателен. Без него не воспринимает.
# установка параметра dpi
dpi = 150
source.set_capability(twain.ICAP_XRESOLUTION, twain.TWTY_FIX32, dpi)
source.set_capability(twain.ICAP_YRESOLUTION, twain.TWTY_FIX32, dpi)
# установка цветности
pixel_type_map = {'bw'   :twain.TWPT_BW,
                  'gray' :twain.TWPT_GRAY,
                  'color':twain.TWPT_RGB}
pixel_type = pixel_type_map['color']
source.set_capability(twain.ICAP_PIXELTYPE, twain.TWTY_UINT16, pixel_type)
# старт сканирования
source.RequestAcquire(0, 0)
result = source.XferImageNatively()
handle, count = result
#twain.DIBToBMFile(handle, "1.bmp") 
# Ну не нужен мне этот чёртов BMP на диске. 
# Как получить доступ к полученному изображению в памяти? Чтобы можно было что-нибудь с ним сделать?
# Ничего не понимаю в этом pytwain. Бросать, видимо, придётся эту затею. Я уже ненавижу этот чёртов модуль.
source.close()
sm.close()
P.S. Вот написано в описании про второй параметр (имя файла) для DIBToBMFile: If not passed, the BMP file will be returned as a string.
Никакой string он не ретурнед. Ошибки он ретурнед, если имя файла не указать.

Отредактировано Pluto (Июль 20, 2017 11:15:26)

Офлайн

#10 Июль 20, 2017 11:19:20

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Работа со сканером. Чем можно воспользоваться? Нашёл только pytwain, но не могу разобраться.

Pluto
# Как получить доступ к полученному изображению в памяти? Чтобы можно было что-нибудь с ним сделать?
Шо значит как? А это что?
 result = source.XferImageNatively()
handle, count = result
я так понимаю handle это ссылка на область в памяти где храниться сосканированая каритика…
не обязательно сохранять ее сразу в файл.. попробуйте например загнать его в qpixmap
pixmap = QPixmap.fromWinHBITMAP(handle) или еще куда, где вы хотите хранить вашу картинку.
А можно просто хранить список хендлов, для дальнейшей обработки, правда тогда нужно смотреть, когда вы делаете close(), освобождаеться ли память или нет…



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Июль 20, 2017 11:20:14)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version