出于我当前正在进行的项目的目的,我需要访问扫描仪 扫描文件 从脚本 Python 在不同的平台上(主要是 Windows 和 macOS)。
今天我要和大家谈谈文档扫描 视窗 远离API威亚 (Windows图像采集),使用库 pywin32。
安装依赖项
在开始编码之前,您当然需要在计算机上安装一些小东西,从最新版本的 Python 3 开始,您可以从 python.org。 安装Python时,记得勾选此框 « 将 python.exe 添加到路径 » 以便可以从终端访问该程序:
可能需要重新启动会话才能使 PATH 更新生效。
接下来我们需要安装 pywin32。 为此,请打开您的终端(执行 ” 窗口>+R”,然后输入 “CMD.EXE”),然后输入以下命令:
pip install pywin32
笔记
笔记 : 如果您对 Python 有一定了解,最好将依赖项安装在 虚拟环境,但在本文中我们将坚持使用最简单的过程。 😉️
就这样,你就准备好了!
列出扫描仪
首先,我们将了解如何列出机器上可用的不同扫描仪。
为此,我们将创建一个小型 Python 脚本,我将其命名为 “列表扫描仪.py” 我将把它放在文件夹中 “扫描仪示例” 它在我的桌子上。 以下是脚本的内容以及适当的注释:
#!/usr/bin/env python3
# On charge la bibliothèque cliente pour les API Win32/COM
import win32com.client
# On charge et on instancie la classe qui permet de lister et manipuler les
# scanners
device_manager = win32com.client.Dispatch("WIA.DeviceManager")
# On parcourt tous les scanners dispo. Le "DeviceManager" va nous retourner
# des objets "DeviceInfo" qui nous permettront de récupérer les propriétés
# des périphériques et de nous y connecter par la suite.
for device_info in device_manager.DeviceInfos:
print("-------------------------------------")
# On affiche une à une les propriétés du scanner
for prop in device_info.Properties:
print("%s: %s" % (prop.Name, str(prop.Value)))
要运行此脚本,
- 我们打开一个终端: ” 窗口> + R”,
- 我们转到包含脚本的文件夹: “光盘 C:UsersFabienDesktopScannerExamples” (1),
- 然后我们启动Python脚本: “python list_scanners.py” (5)。
如果一切顺利,您应该会看到显示的扫描仪列表及其所有属性 (5):
在此屏幕截图中,您可以看到我所做的比之前告诉您的多一点,但不要惊慌,我会快速向您解释这一切:
- 我转到包含脚本的文件夹。
- 我创建并激活一个 虚拟环境 因为我不想直接在系统上安装我的 Python 库,所以我更喜欢限制它(但您不必这样做)。
- 我安装库 “pywin32” 如前所述。
- 我列出了该文件夹的内容以表明该脚本 “列表扫描仪.py” 存在。
- 我运行我的脚本,如上所示。 我们可以看到扫描仪连接到我的机器(我审查了允许识别确切型号的信息)。
一切正常工作并能够运行脚本真正需要的唯一步骤是 1、3 和 5。
扫描文档
现在我们知道如何列出扫描仪,让我们看看如何扫描文档并将结果保存到文件中。
这是我的脚本 “扫描.py” 评论应该是这样的:
#!/usr/bin/env python3
import win32com.client
device_manager = win32com.client.Dispatch("WIA.DeviceManager")
# On prend le premier scanner disponible
#
# ATTENTION : contrairement aux listes Python, les listes Win32/COM
# commencent à 1 et non à 0.
device_info = device_manager.DeviceInfos(1)
# On se connecte au scanner
device = device_info.Connect()
# On récupère le premier "élément" du périphérique (le scanner à plat pour
# moi). Il est possible qu'il y en ait plusieurs sur un scanner plus
# complexe, mais tous les scanners que j'ai utilisés n'en avait qu'un...
scan_source = device.Items(1)
# On numérise le document en sélectionnant au passage le format de l'image
# souhaité.
#
# NOTE¹ : À priori WIA semble supporter du BMP, du PNG, du JPEG etc. mais
# je n'ai jamais réussi à obtenir autre chose que du BMP (c'est
# peut-être dépendant des drivers ?). Je vous recommande donc de
# choisir BMP et de convertir vous-même l'image dans un autre
# format après coup, en utilisant la bibliothèque PIL par exemple.
#
# NOTE² : la constante « win32com.client.constants.wiaFormatBMP » n'existe
# qu'après avoir exécuté « win32com.client.Dispatch("WIA.DeviceManager") »
# dans le script.
#
# Si jamais cette constante n'était pas disponible pour une raison
# ou pour une autre, sachez que vous pouvez la remplacer par la
# string suivante : "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}".
wia_image = scan_source.Transfer(win32com.client.constants.wiaFormatBMP)
# On sauvegarde l'image dans le fichier "out.bmp" dans le dossier courant
wia_image.SaveFile("out.bmp")
我们可以使用与之前相同的方式启动脚本,使用命令 “Python扫描.py” :
在上面的截图中,我们可以看到该文件 “输出.bmp” 已根据我们的命令调用创建。 😃️
更改扫描设置
WIA API允许我们在扫描仪上配置一些参数,例如清晰度、对比度、亮度等。
这是一个显示可用选项的小脚本:
#!/usr/bin/env python3
import win32com.client
device_manager = win32com.client.Dispatch("WIA.DeviceManager")
device_info = device_manager.DeviceInfos(1)
device = device_info.Connect()
scan_source = device.Items(1)
# On liste les différents réglages du scanner
for prop in scan_source.Properties:
print("%s: %s" % (prop.Name, str(prop.Value)))
这是执行上面的脚本后扫描仪给我的结果:
Item Name: Scan Full Item Name: 0000RootScan Item Flags: 532483 Color Profile Name: C:Windowssystem32spooldriverscolorsRGB Color Space Profile.icm Access Rights: 1 Lamp Warm up Time: 120 Current Intent: 0 Horizontal Resolution: 200 Vertical Resolution: 200 Horizontal Start Position: 0 Vertical Start Position: 0 Horizontal Extent: 1700 Vertical Extent: 2340 Rotation: 0 Brightness: 0 Contrast: 0 Item Size: 0 Data Type: 3 Bits Per Pixel: 24 Compression: 0 Channels Per Pixel: 3 Bits Per Channel: 8 Photometric Interpretation: 0 Planar: 0 Buffer Size: 27262976 Threshold: 128 Filename extension: BMP Media Type: 2 Preferred Format: {B96B3CAB-0728-11D3-9D7B-0000F81EF32E} # <= GUID correspondant à BMP Format: {B96B3CAB-0728-11D3-9D7B-0000F81EF32E} # <= GUID correspondant à BMP Pixels Per Line: 1700 Bytes Per Line: 5100 Number of Lines: 2340
在这里我们可以看到 API 使我们能够访问相当多的参数。 我们还可以看到参数的名称可以包含空格,所以稍后你必须小心这一点......🙃️
笔记
笔记 : 在下面的示例中,我将使用Python的REPL(命令行界面)语法:
- 以三个 V 字形开头的线条 (>>>) 是 Python 指令,因为它们可以写在脚本中,
- 以及以三个小点开头的行(...)允许他们显示上一条指令的结果。
现在我们已经列出了可用参数,我们将了解如何修改它们。 以参数为例 “对比”。
要读取此参数的值,您可以按如下方式查询 API:
>>> scan_source.Properties("Contrast").Value
... 0
如果您想更改此值,只需分配一个新值即可:
>>> scan_source.Properties("Contrast").Value = 1000 # +100% de contraste
我们可以验证我们的更改是否已被考虑在内:
>>> scan_source.Properties("Contrast").Value
... 1000
这里我们可能会感到惊讶的是,有必要定义这个参数来 1000 增加对比度 100%...这是 API 的任意选择(并且可能取决于 司机 对于某些参数)。 幸运的是,可以知道每个参数的最小值和最大值,以及它们的“粒度”:
>>> scan_source.Properties("Contrast").SubTypeMin
... -1000
>>> scan_source.Properties("Contrast").SubTypeMax
... 1000
>>> scan_source.Properties("Contrast").SubTypeStep
... 1
为了将各个部分放在一起,这里有一个脚本,它可以扫描文档,并与 +50% 在第一个可用的扫描仪上:
#!/usr/bin/env python3
import win32com.client
device_manager = win32com.client.Dispatch("WIA.DeviceManager")
device_info = device_manager.DeviceInfos(1)
device = device_info.Connect()
scan_source = device.Items(1)
scan_source.Properties("Contrast").Value = scan_source.Properties("Contrast").SubTypeMax // 2
wia_image = scan_source.Transfer(win32com.client.constants.wiaFormatBMP)
wia_image.SaveFile("out.bmp")
事情并没有那么复杂
最后我们可以看到这个API非常容易使用,唯一的困难来自于微软的文档,它过于理论和冗长,并且来自于 pywin32 / 蟒蛇com 这可能缺乏有针对性的例子。
如果您想深入研究该主题,我将为您提供以下各种有用文档的链接:
以后的文章再见! 😉️