我正在开发一个使用平板扫描仪的 Django 项目。连接到扫描仪需要很长时间。所以我正在寻找一种重用扫描程序实例的方法。
序列化似乎是解决此问题的首选方法。不幸的是,我无法序列化或腌制扫描程序实例。我不断遇到错误,告诉我序列化失败。
是否有替代方法可以重复使用同一扫描程序实例进行多次扫描?一个后端技巧还是一些前端魔术?(注意,我对前端开发一无所知。
我们可以作弊一点!
该项目将在本地计算机上脱机运行,根本没有互联网或网络连接。这可能会提供原本不安全的选项。
我用于扫描的东西
- 理智,用于访问扫描仪的软件包
- python3-sane,一个 Python 的 sane 包装器
- 图像扫描,扫描仪驱动程序
环顾四周后,我发现了RPyC。本教程提供了一个工作示例,我在几分钟内就运行了它。
该服务启动并连接到扫描程序。多个客户端可以调用服务并立即扫描。
import rpyc
import sane
class MyService(rpyc.Service):
def __init__(self):
self.scanner = Scanner()
def on_connect(self, conn):
pass
def on_disconnect(self, conn):
pass
def exposed_scan_image(self):
self.scanner.low_dpi_scan('scanner_service')
class Scanner(object):
"""
The Scanner class is used to interact with flatbed scanners.
"""
def __init__(self):
sane.init()
self.device_name = None
self.error_message = None
self.device = self.get_device()
def get_device(self):
"""
Return the first detected scanner and set the name.
@return: sane.SaneDev
"""
devices = sane.get_devices()
print('Available devices:', devices)
# Empty list means no scanner is connect or the connected scanner is
# already being used
if not devices:
self.error_message = 'Scanner disconnect or already being used.'
print(self.error_message)
return None
# open the first scanner you see
try:
device = sane.open(devices[0][0])
except Exception as e:
self.error_message = e
print(e)
return None
brand = devices[0][1]
model = devices[0][2]
self.device_name = "{brand}_{model}".format(
brand=brand,
model=model
)
print("Connected to:", self.device_name)
# set to color scanning mode, this is not always the default mode
device.mode = 'color'
return device
def low_dpi_scan(self, file_name):
"""
Scan at 300 dpi and store as jpeg.
@param file_name: string
"""
image = self.scan_image(300)
image.save(file_name+'.jpeg')
def scan_image(self, dpi):
"""
Scan an image.
@param dpi: integer
@return: image file
"""
self.device.resolution = dpi
self.device.start()
image = self.device.snap()
return image
if __name__ == "__main__":
from rpyc.utils.server import ThreadedServer
t = ThreadedServer(MyService(), port=18861)
t.start()