天天看点

(转)在C#中使用WIA获取扫描仪数据(四、通过编程方式扫描图像)

在前面几节,我通过调用CommonDialog对象的ShowAcquireImage方法来扫描图像,这是一个弹出选择设备对话框,让用户自己扫描的过程。有时候,我们不想把过程弄得那么复杂,只想用户点击按钮后,自动开始扫描。本节我将尝试这个需求。

WIAAL模型

在开始代码前,再回顾以下WIAAL模型,这里选取其中的一小部分:

(转)在C#中使用WIA获取扫描仪数据(四、通过编程方式扫描图像)

 和 

(转)在C#中使用WIA获取扫描仪数据(四、通过编程方式扫描图像)

从上图不难想象,一台扫描仪,实际上就是一个Device对象,因此,我们可以通过DeviceManager来“获 取”这台设备的“引用”,然后通过得到的Device对象,执行相应的扫描工作。从而跳过了使用ShowAcquireImage方法带来的一系列“多余 的鼠标操作问题”。

获取Device对象

按照上面思路,首先需要建立一个DeviceManager对象:

DeviceManager 
manager 
= new 
DeviceManagerClass
();      

然后获取Device对象,在这里,我假设我的电脑上只有一台扫描仪,因此不做诸如“判断使用哪台扫描仪进行扫描”之类的操作。

Device 
device 
= null
;



foreach 
(DeviceInfo 
info 
in 
manager
.DeviceInfos
)

{

    if 
(info
.Type 
!= WiaDeviceType
.ScannerDeviceType
) continue
;

    device 
= info
.Connect
();

    break
;

}      

扫描图像

WIA把Device设备的图像数据看做一个个Item对象,可以通过方法GetItem(ItemID)来实现。不过,对于扫描仪做种东西,和数码相机不同,一般只有一个Item对象,因此可以简单的使用数组的方法(注意:index是从1开始的,而不是从0):

Item 
item 
= device
.Items
[1];      

最后,调用CommonDialog的ShowTransfer方法,用一个进度条,来显示扫描过程:

CommonDialogClass 
cdc 
= new 
WIA
.CommonDialogClass
();

ImageFile 
imageFile 
= cdc
.ShowTransfer
(item
,

    "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
,

    true
) as 
ImageFile
;



if 
(imageFile 
!= null
)

{

    var 
buffer 
= imageFile
.FileData
.get_BinaryData
() as byte
[];

    using 
(MemoryStream 
ms 
= new 
MemoryStream
())

    {

        ms
.Write
(buffer
, 0, buffer
.Length
);

        pictureBox1
.Image 
= Image
.FromStream
(ms
);

    }

}      

关于ShowTransfer方法

CommonDialog的ShowTransfer方法,实际上就是ShowAcquireImage方法的最后一个步骤,显示一个获取图片的进度条:

(转)在C#中使用WIA获取扫描仪数据(四、通过编程方式扫描图像)

声明如下:

public virtual object 
ShowTransfer
(Item 
Item
, string 
FormatID
, bool 
CancelError
);      

对于第二个参数,FormatID,可以使用以下值:

  • wiaFormatBMP ({B96B3CAB-0728-11D3-9D7B-0000F81EF32E})
  • wiaFormatPNG ({B96B3CAF-0728-11D3-9D7B-0000F81EF32E})
  • wiaFormatGIF ({B96B3CB0-0728-11D3-9D7B-0000F81EF32E})
  • wiaFormatJPEG ({B96B3CAE-0728-11D3-9D7B-0000F81EF32E})
  • wiaFormatTIFF ({B96B3CB1-0728-11D3-9D7B-0000F81EF32E})