图形/图像
(转)在C#中使用WIA获取扫描仪数据(一)
2017-02-05 14:34:56

稍等除了TWAIN外还有微软WIA驱动。

(转)在C#中使用WIA获取扫描仪数据(一)      

WIA(Windows Image Acquire,最新版本2.0)是Windows中一组从设备中捕获图像的标准API集合,它可以从设备(例如扫描仪、数码相机)中获取静态图像,以及管理这些设备。它既是API,又是DDI(Device Driver Interface)。因此,只要是满足这个规范的设备,都能够利用WIA直接和应用程序交互,而不是通过驱动。WIA甚至提供了统一的对话框来获取图片。

WIA是基于Com的,有两种使用方式:

c++:使用WIA自定义接口 其他:使用WIAAL(WIA Automation Layer)。 注:在Windows XP sp1以前的版本,WIAAL还不存在,因此第二种方式用的是WIA Scripting Model。

在.Net中使用WIA,我们用的是第二种方法。接下来做一个简单的图像扫描程序:

界面新建一个WinForm应用程序,在上面添加一个按钮和一个图片框,点击按钮时启动扫描进程,然后在图片框中显示图像,应用程序界面如下:

 

使用WIAVisual Studio 2008有一个好处,可以自动装配Com组件,在工程中添加一个WIA的COM引用:

 

 点击确定后,会在工程引用中添加一个WIA.Interop.dll的文件,可以在对象浏览器中查看它:

 

打开扫描对话框接下来可以利用WIA来进行扫描了,步骤很简单,首先引用命名空间:

using

WIA

;接下来,在button的Click事件中,添加如下代码:

ImageFile

imageFile

= null

;

CommonDialogClass

cdc

= new

WIA

.CommonDialogClass

();

 

try

 

{

    imageFile

= cdc

.ShowAcquireImage

(WIA

.WiaDeviceType

.ScannerDeviceType

,

                                     WIA

.WiaImageIntent

.TextIntent

,

                                     WIA

.WiaImageBias

.MaximizeQuality

,

                                     "{00000000-0000-0000-0000-000000000000}"

,

                                     true

,

                                     true

,

                                     false

);

}

catch

(System

.Runtime

.InteropServices

.COMException

)

{

    imageFile

= null

;

}WIA会自动弹出标准扫描对话框,进行扫描操作:

 

获取图像调用ShowAcquireImage后,扫描后的数据就保存在ImageFile对象里了。用以下方法读取ImageFile中的数据(该方法很傻很傻……很傻)

if

(imageFile

!= null

)

{

 

    imageFile

.SaveFile

(@"c:\1.bmp"

);

    using

(FileStream

stream

= new

FileStream

(@"c:\1.bmp"

, FileMode

.Open

,

        FileAccess

.Read

, FileShare

.Read

))

    {

        pictureBox1

.Image

= Image

.FromStream

(stream

);

    }    File

.Delete

(@"c:\1.bmp"

);

}结果如下:

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lsj_zrp/archive/2009/12/25/5070162.aspx

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

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

WIAAL模型

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

 

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

获取Device对象

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

DeviceManagermanager=newDeviceManagerClass();

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

Devicedevice=null;foreach(DeviceInfoinfoinmanager.DeviceInfos) {if(info.Type!=WiaDeviceType.ScannerDeviceType)continue;device=info.Connect();break;}

 

扫描图像

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

Itemitem=device.Items[1];

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

CommonDialogClasscdc=newWIA.CommonDialogClass();ImageFileimageFile=cdc.ShowTransfer(item,"{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}",true)asImageFile;if(imageFile!=null) {varbuffer=imageFile.FileData.get_BinaryData()as byte[];using(MemoryStreamms=newMemoryStream()) {ms.Write(buffer, 0,buffer.Length);pictureBox1.Image=Image.FromStream(ms); }}关于ShowTransfer方法

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

声明如下:

public virtual objectShowTransfer(ItemItem,stringFormatID,boolCancelError);

对于第二个参数,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})