第一步 安装twain
注意,直接pip install twain是没有的,必须要通过whl离线安装
首先下载twain的whl文件,网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#twainmodule
下载自己Python对应的版本,例如我是python3.6.7 32位,就选cp36的
然后通过pip install twain-1.0.4-cp36-cp36m-win32.whl安装
第二步,导入twain,并测试扫描
在自己的py代码中,输入下面的代码,然后执行
import twain
sm = twain.SourceManager(0)
ss = sm.OpenSource()
ss.RequestAcquire(0,0)
rv = ss.XferImageNatively()
if rv:
(handle, count) = rv
twain.DIBToBMFile(handle, 'image.bmp')
会弹出扫描仪选择窗口
选中自己的扫描仪名称,扫描仪就会启动,图像文件名image.bmp
我们可以用GetSourceName()来获取扫描仪的名称,然后下次把扫描仪名称传入OpenSource(扫描仪名称)中,就不会弹出选择来源的对话框了
import twain
sm = twain.SourceManager(0)
ss = sm.OpenSource()
name = ss.GetSourceName()
print(name) # FBH6315+
ss.RequestAcquire(0,0)
rv = ss.XferImageNatively()
if rv:
(handle, count) = rv
twain.DIBToBMFile(handle, 'image.bmp')
三,设置扫描范围,颜色,dpi,扫描仪设置界面等
打开安装包site-packages,里面有个twain.py的文件,打开twain.py,在代码最下方,有个acquire()的方法,调用这个方法就可以自定义扫描了,其中的参数分别表示:
path:必传参数,图像保存的位置,其他的参数都可以不传
ds_name:扫描仪名称
dpi:dpi
pixel_type:颜色模式,有“bw”、“gray”、“color”三个选项,第二个和第三个是灰度和彩色,第一个不知道啥
frame:扫描范围,传入一个元组,(left, top, right, bottom)表示扫描的左上右下的范围,单位是英寸,例如要设置A4大小,A4是210mmX297mm,分别换算成英寸(除以25.4),
frame=(0.0, 0.0 ,8.27 ,11.7)传入这个参数,如果要旋转90度扫描(注意不是图像旋转90度),就把8.27和11.7换一下
show_ui:显示扫描仪设置界面,默认是False不显示,设置为True就是显示
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
Required argument:
path -- path where to save image
Keyword arguments:
ds_name -- name of twain data source, if not provided user will be presented with selection dialog
dpi -- resolution in dots per inch
pixel_type -- can be 'bw', 'gray', 'color'
bpp -- bits per pixel
frame -- tuple (left, top, right, bottom) scan area in inches
parent_window -- can be Tk, Wx, Gtk window object or Win32 window handle
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
'''
四、错误处理
我们在程序中直接调用acquire()方法,就能自定义扫描,代码如下
import twain
twain.acquire(r'./test.bmp')
这样执行可能会弹出错误AttributeError: module 'twain' has no attribute 'acquire',就是twain.py中没有acquire模块,但是在twain.py中确实是存在acquire方法的,这是因为在Python环境中还存在其他twain模块,导致找不到acquire模块
解决方法,直接把twain.py复制一份,改一下名字,例如twain_module.py,把这个作为模块导入,一切就ok了
import twain_module
twain_module.acquire(r'./test.bmp') #默认参数扫描
import twain_module
twain_module.acquire(r'./test.bmp',dpi=300,pixel_type="color") # 设置dpi300,彩色模式
扫描设置也就生效了
.。。。。
还没完!!!
还有两个问题
第一,如果我们设置的图像后缀名不是bmp,例如jpg,那么会报错,
ModuleNotFoundError: No module named 'Image' ,并且图像也没保存,我们打开twian_module.py,发现twian_module.py中导入了PIL包,它其实是通过PIL转换了格式
但是导入的方式是旧版的import Image,python3.x的导入方式是 from PIL import Image,我们将twain_module.py中的全部改一下(一共两处),就ok了
第二,如果我们设置了不是bmp格式的图像,会发现我们设置的dpi不生效,一直是96,在查看twian_module.py代码后,我们发现,如果是bmp格式的图形,twain_module会直接设置图像dpi,当时如果不是bmp,会通过PIL转换后保存,但是在PIL保存时并没有设置dpi
我们自己手动修改一下,给PIL保存的时候加上dpi
1.先在sd.acquire_file中传入dpi=dpi
sd.acquire_file(before=before, after=after, show_ui=show_ui, dpi=dpi)
2.再修改acquire_file方法
def acquire_file(self, before, after=lambda more: None, show_ui=True, modal=False,dpi=None):
if dpi is None:
dpi = 96
..........................
if ext != '.bmp':
# import Image
Image.open(bmppath).save(filepath,dpi=(dpi,dpi))
os.remove(bmppath)
这两步其实也简单,大家自己读一下twain.py的源码后明白了
结束!
最后将我的twain_module.py上传上来,将文件放在你程序的同级,或者site-packages中,都可以(前提是你安装过twain)
'''
Created on Sep 4, 2011
@author: misha
'''
from ctypes import *
import weakref
import sys
from PIL import Image
TWON_PROTOCOLMAJOR = 2
TWON_PROTOCOLMINOR = 1
DF_DSM2 = 0x10000000
DF_APP2 = 0x20000000
DF_DS2 = 0x40000000
ACAP_AUDIOFILEFORMAT = 4609
ACAP_XFERMECH = 4610
CAP_ALARMS = 4120
CAP_ALARMVOLUME = 4121
CAP_AUTHOR = 4096
CAP_AUTOFEED = 4103
CAP_AUTOMATICCAPTURE = 4122
CAP_AUTOMATICSENSEMEDIUM = 4155
CAP_AUTOSCAN = 4112
CAP_BATTERYMINUTES = 4146
CAP_BATTERYPERCENTAGE = 4147
CAP_CAMERAENABLED = 4150
CAP_CAMERAORDER = 4151
CAP_CAMERAPREVIEWUI = 4129
CAP_CAMERASIDE = 4148
CAP_CAPTION = 4097
CAP_CLEARBUFFERS = 4125
CAP_CLEARPAGE = 4104
CAP_CUSTOMBASE = 32768
CAP_CUSTOMDSDATA = 4117
CAP_CUSTOMINTERFACEGUID = 4156
CAP_DEVICEEVENT = 4130
CAP_DEVICEONLINE = 4111
CAP_DEVICETIMEDATE = 4127
CAP_DUPLEX = 4114
CAP_DUPLEXENABLED = 4115
CAP_ENABLEDSUIONLY = 4116
CAP_ENDORSER = 4118
CAP_EXTENDEDCAPS = 4102
CAP_FEEDERALIGNMENT = 4141
CAP_FEEDERENABLED = 4098
CAP_FEEDERLOADED = 4099
CAP_FEEDERORDER = 4142
CAP_FEEDERPOCKET = 4154
CAP_FEEDERPREP = 4153
CAP_FEEDPAGE = 4105
CAP_INDICATORS = 4107
CAP_JOBCONTROL = 4119
CAP_LANGUAGE = 4140
CAP_MAXBATCHBUFFERS = 4126
CAP_MICRENABLED = 4152
CAP_PAGEMULTIPLEACQUIRE = 4131
CAP_PAPERBINDING = 4143
CAP_PAPERDETECTABLE = 4109
CAP_PASSTHRU = 4145
CAP_POWERDOWNTIME = 4148
CAP_POWERSUPPLY = 4128
CAP_PRINTER = 4134
CAP_PRINTERENABLED = 4135
CAP_PRINTERINDEX = 4136
CAP_PRINTERMODE = 4137
CAP_PRINTERSTRING = 4138
CAP_PRINTERSUFFIX = 4139
CAP_REACQUIREALLOWED = 4144
CAP_REWINDPAGE = 4106
CAP_SEGMENTED = 4149
CAP_SERIALNUMBER = 4132
CAP_SUPPORTEDCAPS = 4101
CAP_SUPPORTEDCAPSEXT = 4108
CAP_THUMBNAILSENABLED = 4113
CAP_TIMEBEFOREFIRSTCAPTURE = 4123
CAP_TIMEBETWEENCAPTURES = 4124
CAP_TIMEDATE = 4100
CAP_UICONTROLLABLE = 4110
CAP_XFERCOUNT = 1
DAT_AUDIOFILEXFER = 513
DAT_AUDIOINFO = 514
DAT_AUDIONATIVEXFER = 515
DAT_CAPABILITY = 1
DAT_CIECOLOR = 262
DAT_CUSTOMBASE = 32768
DAT_CUSTOMDSDATA = 12
DAT_DEVICEEVENT = 13
DAT_ENTRYPOINT = 0x0403
DAT_EVENT = 2
DAT_EXTIMAGEINFO = 267
DAT_FILESYSTEM = 14
DAT_GRAYRESPONSE = 263
DAT_IDENTITY = 3
DAT_IMAGEFILEXFER = 261
DAT_IMAGEINFO = 257
DAT_IMAGELAYOUT = 258
DAT_IMAGEMEMXFER = 259
DAT_IMAGENATIVEXFER = 260
DAT_JPEGCOMPRESSION = 265
DAT_NULL = 0
DAT_PALETTE8 = 266
DAT_PARENT = 4
DAT_PASSTHRU = 15
DAT_PENDINGXFERS = 5
DAT_RGBRESPONSE = 264
DAT_SETUPFILEXFER = 7
DAT_SETUPMEMXFER = 6
DAT_STATUS = 8
DAT_TWUNKIDENTITY = 11
DAT_USERINTERFACE = 9
DAT_XFERGROUP = 10
DG_AUDIO = 4
DG_CONTROL = 1
DG_IMAGE = 2
ICAP_AUTOBRIGHT = 4352
ICAP_AUTODISCARDBLANKPAGES = 4404
ICAP_AUTOMATICBORDERDETECTION = 4432
ICAP_AUTOMATICCOLORENABLED = 4441
ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE = 4442
ICAP_AUTOMATICCROPUSESFRAME = 4439
ICAP_AUTOMATICDESKEW = 4433
ICAP_AUTOMATICLENGTHDETECTION = 4440
ICAP_AUTOMATICROTATE = 4434
ICAP_AUTOSIZE = 4438
ICAP_BARCODEDETECTIONENABLED = 4407
ICAP_BARCODEMAXRETRIES = 4412
ICAP_BARCODEMAXSEARCHPRIORITIES = 4409
ICAP_BARCODESEARCHMODE = 4411
ICAP_BARCODESEARCHPRIORITIES = 4410
ICAP_BARCODETIMEOUT = 4413
ICAP_BITDEPTH = 4395
ICAP_BITDEPTHREDUCTION = 4396
ICAP_BITORDER = 4380
ICAP_BITORDERCODES = 4390
ICAP_BRIGHTNESS = 4353
ICAP_CCITTKFACTOR = 4381
ICAP_COLORMANAGEMENTENABLED = 4443
ICAP_COMPRESSION = 256
ICAP_CONTRAST = 4355
ICAP_CUSTHALFTONE = 4356
ICAP_EXPOSURETIME = 4357
ICAP_EXTIMAGEINFO = 4399
ICAP_FEEDERTYPE = 4436
ICAP_FILTER = 4358
ICAP_FLASHUSED = 4359
ICAP_FLASHUSED2 = 4422
ICAP_FLIPROTATION = 4406
ICAP_FRAMES = 4372
ICAP_GAMMA = 4360
ICAP_HALFTONES = 4361
ICAP_HIGHLIGHT = 4362
ICAP_ICCPROFILE = 4437
ICAP_IMAGEDATASET = 4398
ICAP_IMAGEFILEFORMAT = 4364
ICAP_IMAGEFILTER = 4423
ICAP_IMAGEMERGE = 4444
ICAP_IMAGEMERGEHEIGHTTHRESHOLD = 4445
ICAP_JPEGPIXELTYPE = 4392
ICAP_JPEGQUALITY = 4435
ICAP_LAMPSTATE = 4365
ICAP_LIGHTPATH = 4382
ICAP_LIGHTSOURCE = 4366
ICAP_MAXFRAMES = 4378
ICAP_MINIMUMHEIGHT = 4400
ICAP_MINIMUMWIDTH = 4401
ICAP_NOISEFILTER = 4424
ICAP_ORIENTATION = 4368
ICAP_OVERSCAN = 4425
ICAP_PATCHCODEDETECTIONENABLED = 4415
ICAP_PATCHCODEMAXRETRIES = 4420
ICAP_PATCHCODEMAXSEARCHPRIORITIES = 4417
ICAP_PATCHCODESEARCHMODE = 4419
ICAP_PATCHCODESEARCHPRIORITIES = 4418
ICAP_PATCHCODETIMEOUT = 4421
ICAP_PHYSICALHEIGHT = 4370
ICAP_PHYSICALWIDTH = 4369
ICAP_PIXELFLAVOR = 4383
ICAP_PIXELFLAVORCODES = 4391
ICAP_PIXELTYPE = 257
ICAP_PLANARCHUNKY = 4384
ICAP_ROTATION = 4385
ICAP_SHADOW = 4371
ICAP_SUPPORTEDBARCODETYPES = 4408
ICAP_SUPPORTEDEXTIMAGEINFO = 4446
ICAP_SUPPORTEDPATCHCODETYPES = 4416
ICAP_SUPPORTEDSIZES = 4386
ICAP_THRESHOLD = 4387
ICAP_TILES = 4379
ICAP_TIMEFILL = 4394
ICAP_UNDEFINEDIMAGESIZE = 4397
ICAP_UNITS = 258
ICAP_XFERMECH = 259
ICAP_XNATIVERESOLUTION = 4374
ICAP_XRESOLUTION = 4376
ICAP_XSCALING = 4388
ICAP_YNATIVERESOLUTION = 4375
ICAP_YRESOLUTION = 4377
ICAP_YSCALING = 4389
ICAP_ZOOMFACTOR = 4414
MSG_CHANGEDIRECTORY = 2049
MSG_CHECKSTATUS = 513
MSG_CLOSEDS = 1026
MSG_CLOSEDSM = 770
MSG_CLOSEDSOK = 259
MSG_CLOSEDSREQ = 258
MSG_CREATEDIRECTORY = 2050
MSG_CUSTOMBASE = 32768
MSG_DELETE = 2051
MSG_DEVICEEVENT = 260
MSG_DISABLEDS = 1281
MSG_ENABLEDS = 1282
MSG_ENABLEDSUIONLY = 1283
MSG_ENDXFER = 1793
MSG_FORMATMEDIA = 2052
MSG_GET = 1
MSG_GETCLOSE = 2053
MSG_GETCURRENT = 2
MSG_GETDEFAULT = 3
MSG_GETFIRST = 4
MSG_GETFIRSTFILE = 2054
MSG_GETINFO = 2055
MSG_GETNEXT = 5
MSG_GETNEXTFILE = 2056
MSG_NULL = 0
MSG_OPENDS = 1025
MSG_OPENDSM = 769
MSG_PASSTHRU = 2305
MSG_PROCESSEVENT = 1537
MSG_QUERYSUPPORT = 8
MSG_RENAME = 2057
MSG_RESET = 7
MSG_SET = 6
MSG_USERSELECT = 1027
MSG_XFERREADY = 257
TWAF_AIFF = 1
TWAF_AU = 3
TWAF_SND = 4
TWAF_WAV = 0
TWAL_ALARM = 0
TWAL_BARCODE = 3
TWAL_DOUBLEFEED = 4
TWAL_FEEDERERROR = 1
TWAL_FEEDERWARNING = 2
TWAL_JAM = 5
TWAL_PATCHCODE = 6
TWAL_POWER = 7
TWAL_SKEW = 8
TWAS_AUTO = 1
TWAS_CURRENT = 2
TWAS_NONE = 0
TWBCOR_ROT0 = 0
TWBCOR_ROT180 = 2
TWBCOR_ROT270 = 3
TWBCOR_ROT90 = 1
TWBCOR_ROTX = 4
TWBD_HORZ = 0
TWBD_HORZVERT = 2
TWBD_VERT = 1
TWBD_VERTHORZ = 3
TWBO_LSBFIRST = 0
TWBO_MSBFIRST = 1
TWBP_AUTO = -1
TWBP_DISABLE = -2
TWBR_CUSTHALFTONE = 2
TWBR_DIFFUSION = 3
TWBR_HALFTONE = 1
TWBR_THRESHOLD = 0
TWBT_2OF5DATALOGIC = 15
TWBT_2OF5IATA = 16
TWBT_2OF5INDUSTRIAL = 13
TWBT_2OF5INTERLEAVED = 1
TWBT_2OF5MATRIX = 14
TWBT_2OF5NONINTERLEAVED = 2
TWBT_3OF9 = 0
TWBT_3OF9FULLASCII = 17
TWBT_CODABAR = 6
TWBT_CODABARWITHSTARTSTOP = 18
TWBT_CODE128 = 4
TWBT_CODE93 = 3
TWBT_EAN13 = 10
TWBT_EAN8 = 9
TWBT_MAXICODE = 19
TWBT_PDF417 = 12
TWBT_POSTNET = 11
TWBT_UCC128 = 5
TWBT_UPCA = 7
TWBT_UPCE = 8
TWCB_AUTO = 0
TWCB_CLEAR = 1
TWCB_NOCLEAR = 2
TWCC_BADCAP = 6
TWCC_BADDEST = 12
TWCC_BADPROTOCOL = 9
TWCC_BADVALUE = 10
TWCC_BUMMER = 1
TWCC_CAPBADOPERATION = 14
TWCC_CAPSEQERROR = 15
TWCC_CAPUNSUPPORTED = 13
TWCC_CHECKDEVICEONLINE = 23
TWCC_CUSTOMBASE = 32768
TWCC_DAMAGEDCORNER = 25
TWCC_DENIED = 16
TWCC_DOCTOODARK = 28
TWCC_DOCTOOLIGHT = 27
TWCC_FILEEXISTS = 17
TWCC_FILENOTFOUND = 18
TWCC_FILEWRITEERROR = 22
TWCC_FOCUSERROR = 26
TWCC_LOWMEMORY = 2
TWCC_MAXCONNECTIONS = 4
TWCC_NODS = 3
TWCC_NOMEDIA = 29
TWCC_NOTEMPTY = 19
TWCC_OPERATIONERROR = 5
TWCC_PAPERDOUBLEFEED = 21
TWCC_PAPERJAM = 20
TWCC_SEQERROR = 11
TWCC_SUCCESS = 0
TWCP_BITFIELDS = 12
TWCP_GROUP31D = 2
TWCP_GROUP31DEOL = 3
TWCP_GROUP32D = 4
TWCP_GROUP4 = 5
TWCP_JBIG = 8
TWCP_JPEG = 6
TWCP_LZW = 7
TWCP_NONE = 0
TWCP_PACKBITS = 1
TWCP_PNG = 9
TWCP_RLE4 = 10
TWCP_RLE8 = 11
TWCS_BOTH = 0
TWCS_BOTTOM = 2
TWCS_TOP = 1
TWCY_AFGHANISTAN = 1001
TWCY_ALBANIA = 355
TWCY_ALGERIA = 213
TWCY_AMERICANSAMOA = 684
TWCY_ANDORRA = 27
TWCY_ANGOLA = 1002
TWCY_ANGUILLA = 8090
TWCY_ANTIGUA = 8091
TWCY_ARGENTINA = 54
TWCY_ARMENIA = 374
TWCY_ARUBA = 297
TWCY_ASCENSIONI = 247
TWCY_AUSTRALIA = 61
TWCY_AUSTRIA = 43
TWCY_AZERBAIJAN = 994
TWCY_BAHAMAS = 8092
TWCY_BAHRAIN = 973
TWCY_BANGLADESH = 880
TWCY_BARBADOS = 8093
TWCY_BELARUS = 375
TWCY_BELGIUM = 32
TWCY_BELIZE = 501
TWCY_BENIN = 229
TWCY_BERMUDA = 8094
TWCY_BHUTAN = 1003
TWCY_BOLIVIA = 591
TWCY_BOSNIAHERZGO = 387
TWCY_BOTSWANA = 267
TWCY_BRAZIL = 55
TWCY_BRITAIN = 6
TWCY_BRITVIRGINIS = 8095
TWCY_BRUNEI = 673
TWCY_BULGARIA = 359
TWCY_BURKINAFASO = 1004
TWCY_BURMA = 1005
TWCY_BURUNDI = 1006
TWCY_CAMAROON = 237
TWCY_CAMBODIA = 855
TWCY_CANADA = 2
TWCY_CAPEVERDEIS = 238
TWCY_CAYMANIS = 8096
TWCY_CENTRALAFREP = 1007
TWCY_CHAD = 1008
TWCY_CHILE = 56
TWCY_CHINA = 86
TWCY_CHRISTMASIS = 1009
TWCY_COCOSIS = 1009
TWCY_COLOMBIA = 57
TWCY_COMOROS = 1010
TWCY_CONGO = 1011
TWCY_COOKIS = 1012
TWCY_COSTARICA = 506
TWCY_CROATIA = 385
TWCY_CUBA = 5
TWCY_CYPRUS = 357
TWCY_CZECHOSLOVAKIA = 42
TWCY_CZECHREPUBLIC = 420
TWCY_DENMARK = 45
TWCY_DIEGOGARCIA = 246
TWCY_DJIBOUTI = 1013
TWCY_DOMINCANREP = 8098
TWCY_DOMINICA = 8097
TWCY_EASTERIS = 1014
TWCY_ECUADOR = 593
TWCY_EGYPT = 20
TWCY_ELSALVADOR = 503
TWCY_EQGUINEA = 1015
TWCY_ERITREA = 291
TWCY_ESTONIA = 372
TWCY_ETHIOPIA = 251
TWCY_FAEROEIS = 298
TWCY_FALKLANDIS = 1016
TWCY_FIJIISLANDS = 679
TWCY_FINLAND = 358
TWCY_FRANCE = 33
TWCY_FRANTILLES = 596
TWCY_FRGUIANA = 594
TWCY_FRPOLYNEISA = 689
TWCY_FUTANAIS = 1043
TWCY_GABON = 241
TWCY_GAMBIA = 220
TWCY_GEORGIA = 995
TWCY_GERMANY = 49
TWCY_GHANA = 233
TWCY_GIBRALTER = 350
TWCY_GREECE = 30
TWCY_GREENLAND = 299
TWCY_GRENADA = 8099
TWCY_GRENEDINES = 8015
TWCY_GUADELOUPE = 590
TWCY_GUAM = 671
TWCY_GUANTANAMOBAY = 5399
TWCY_GUATEMALA = 502
TWCY_GUINEA = 224
TWCY_GUINEABISSAU = 1017
TWCY_GUYANA = 592
TWCY_HAITI = 509
TWCY_HONDURAS = 504
TWCY_HONGKONG = 852
TWCY_HUNGARY = 36
TWCY_ICELAND = 354
TWCY_INDIA = 91
TWCY_INDONESIA = 62
TWCY_IRAN = 98
TWCY_IRAQ = 964
TWCY_IRELAND = 353
TWCY_ISRAEL = 972
TWCY_ITALY = 39
TWCY_IVORYCOAST = 225
TWCY_JAMAICA = 8010
TWCY_JAPAN = 81
TWCY_JORDAN = 962
TWCY_KENYA = 254
TWCY_KIRIBATI = 1018
TWCY_KOREA = 82
TWCY_KUWAIT = 965
TWCY_LAOS = 1019
TWCY_LATVIA = 371
TWCY_LEBANON = 1020
TWCY_LESOTHO = 266
TWCY_LIBERIA = 231
TWCY_LIBYA = 218
TWCY_LIECHTENSTEIN = 41
TWCY_LITHUANIA = 370
TWCY_LUXENBOURG = 352
TWCY_MACAO = 853
TWCY_MACEDONIA