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

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

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

  1. c++:使用WIA自定义接口
  2. 其他:使用WIAAL(WIA Automation Layer)。

注:在Windows XP sp1以前的版本,WIAAL还不存在,因此第二种方式用的是WIA Scripting Model。

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

界面

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

image-thumb39.png(42.89 K)

5/24/2009 6:59:47 AM

使用WIA

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

image-thumb40.png(48.10 K)

5/24/2009 6:59:47 AM

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

image-thumb41.png(9.83 K)

5/24/2009 6:59:47 AM

打开扫描对话框

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

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

  1. ImageFile imageFile = null;
  2. CommonDialogClass cdc = new WIA.CommonDialogClass();
  3. try
  4. {
  5. imageFile = cdc.ShowAcquireImage(WIA.WiaDeviceType.ScannerDeviceType,
  6. WIA.WiaImageIntent.TextIntent,
  7. WIA.WiaImageBias.MaximizeQuality,
  8. "{00000000-0000-0000-0000-000000000000}",
  9. 10.                                     true,
  10. 11.                                     true,
  11. 12.                                     false);

13. }

14. catch (System.Runtime.InteropServices.COMException)

15. {

  1. 16.     imageFile = null;

17. }

复制代码

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

image-thumb42.png(31.45 K)

5/24/2009 6:59:47 AM

获取图像

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

  1. if (imageFile != null)
  2. {
  3. imageFile.SaveFile(@"c:\1.bmp");
  4. using (FileStream stream = new FileStream(@"c:\1.bmp", FileMode.Open,
  5. FileAccess.Read, FileShare.Read))
  6. {
  7. pictureBox1.Image = Image.FromStream(stream);
  8. }    File.Delete(@"c:\1.bmp");

10. }

复制代码

结果如下:

在C#中使用WIA获取扫描仪数据(二、WIA Automation Layer

前文说过,在WIA 2.0 里,有一个叫Automation Layer的东西,来负责WIA和应用程序交互。既然被命名为Automation了,那么意味着比直接试用WIA接口,WIAAL更容易、更方便。实际上的确如此。

关于WIA Automation Layer

文档上说,WIA Automation Layer是一个高级的,全能的图像操作组件,能为应用程序(例如ASP,C#)提供首尾相连的处理能力。利用WIAAL,在程序中可以很容易地从诸如数码相机、扫描仪等图像设备中捕获图像,以及进行简单处理(缩放、旋转)。

对象分级结构

WIAAL的对象不多,总的来说分成来两块,第一块是可以被创建的类(例如在c#里我们用关键字new来创建),另一部分是不能被创建的类(在c#里,这些类虽然也有构造函数,不过即使创建了,也没有任何东西),它们必须由第一种类创建。如下图:

image-thumb44.png(51.69 K)

5/24/2009 7:03:03 AM

可见,上面有我们熟悉的CommonDialog(在Interop后,这些类后面都加上了Class表示实现,例如CommonDialogClass就是CommonDialog的实现)。

改进的例子

在前面的文章中,我用了一个很“囧”的方法来保存图片,实际上大可不必如此,从上面的关系图可以看到,ImageFile对象有一个Vector的对象,该对象保存了图片的像素值。修改代码如下:

  1. if (imageFile != null)
  2. {
  3. var buffer =imageFile.FileData.get_BinaryData() as byte[];
  4. using (MemoryStream ms = new MemoryStream())
  5. {
  6. ms.Write(buffer, 0, buffer.Length);
  7. pictureBox1.Image = Image.FromStream(ms);
  8. }
  9. }

在C#中使用WIA获取扫描仪数据(三、利用Filter处理图片)

WIA Automation Layer不仅能从设备中捕获照片,还能进行简单的处理。当WIA Automation Layer从设备中捕获照片,保存为一个ImageFile对象,我们可以通过访问该ImageFile对象来访问照片的属性。然而,为了保护原来的照片,不能直接通过修改该ImageFile对象的方法修改图片。代替的方法是,使用ImageProcess和一个或多个Filter对象创建一个副本,修改图片。

代码

以下代码把扫描得到的图片顺时针旋转90度:

  1. if (imageFile != null)
  2. {
  3. ImageProcess ip = new ImageProcessClass();
  4. object filterName="RotateFlip";
  5. Object propertyName = "RotationAngle";
  6. Object propertyValue = 90;
  7. 10.     ip.Filters.Add(ip.FilterInfos.get_Item(ref filterName).FilterID, 0);
  8. 11.     ip.Filters[1].Properties.get_Item(ref propertyName).set_Value(ref propertyValue);
  9. 12.
  10. 13.     var buffer =ip.Apply(imageFile).FileData.get_BinaryData() as byte[];
  11. 14.     using (MemoryStream ms = new MemoryStream())
  12. 15.     {
  13. 16.         ms.Write(buffer, 0, buffer.Length);
  14. 17.         pictureBox1.Image = Image.FromStream(ms);
  15. 18.     }
  16. 19.

20. }

复制代码

image-thumb45.png(256.10 K)

5/24/2009 7:08:54 AM

FilterID

以下是可用的FilterID

RotateFlip

以 90 度增量旋转,以及水平或垂直翻转。
RotationAngle  - 如果希望旋转,可将 RotationAngle 属性设置为 90、180 或 270,
                    否则设置为 0 [默认值]
FlipHorizontal - 如果希望水平翻转图像,可将 FlipHorizontal 属性设置为 True,
                    否则设置为 False [默认值]
FlipVertical  - 如果希望垂直翻转图像,可将 FlipVertical 属性设置为 True,
                    否则设置为 False [默认值]
FrameIndex    - 如果希望修改除 ActiveFrame 之外的帧,
                    可将 FrameIndex 属性设置为帧的索引,
                    否则设置为 0 [默认值]

Crop

以指定的左、右、上、下边距裁剪图像。
Left      - 如果希望沿左侧裁剪,可将 Left 属性设置为左边距(单位为像素),
                否则设置为 0 [默认值]
Top        - 如果希望沿顶部裁剪,可将 Top 属性设置为上边距(单位为像素),
                否则设置为 0 [默认值]
Right      - 如果希望沿右侧裁剪,可将 Right 属性设置为右边距(单位为像素),
                否则设置为 0 [默认值]
Bottom    - 如果希望沿底部裁剪,可将 Bottom 属性设置为下边距(单位为像素),
                否则设置为 0 [默认值]
FrameIndex - 如果希望修改除 ActiveFrame 之外的帧,
                可将 FrameIndex 属性设置为帧的索引,否则设置为 0 [默认值]

Scale

将图像缩放到指定的最大宽度和最大高度,如有必要,保留纵横比。
MaximumWidth        - 将 MaximumWidth 属性设置为希望将图像缩放到的宽度(单位为像素)。
MaximumHeight      - 将 MaximumHeight 属性设置为希望将图像缩放到的高度(单位为像素)。
PreserveAspectRatio - 如果希望保持图像当前的纵横比,可将 PreserveAspectRatio 属性设置为 True [默认值],
                          否则设置为 False,图像将被拉伸到MaximumWidth 和 MaximumHeight
FrameIndex          - 如果希望修改除 ActiveFrame 之外的帧,可将 FrameIndex 属性设置为帧的索引,
                      否则设置为 0 [默认值]

Stamp

在指定的 Left 和 Top 坐标处标记指定的 ImageFile。
ImageFile  - 将 ImageFile 属性设置为希望标记的 ImageFile 对象
Left      - 将 Left 属性设置为希望将 ImageFile 标记到的从左侧开始的偏移(单位为像素)[默认值为 0]
Top        - 将 Top 属性设置为希望将 ImageFile 标记到的从顶部开始的偏移(单位为像素)[默认值为 0]
FrameIndex - 如果希望修改除 ActiveFrame 之外的帧,可将 FrameIndex 属性设置为帧的索引,否则设置为0[默认值]

Exif

添加/删除指定的 Exif 属性。
Remove    - 如果希望删除指定的 Exif 属性,可将 Remove 属性设置为 True,否则设置为 False [默认值]以添加
              指定的 exif 属性
ID        - 将 ID 属性设置为希望添加或删除的 PropertyID
Type      - 设置 Type 属性以指示希望添加的 Exif 属性的 WiaImagePropertyType(对于删除则忽略)
Value      - 将 Value 属性设置为希望添加的 Exif 属性的值(对于删除则忽略)
FrameIndex - 如果希望修改除 ActiveFrame 之外的帧,可将 FrameIndex 属性设置为帧的索引,否则设置为0[默认值]
Frame
Remove    - 如果希望删除指定的 FrameIndex,可将 Remove 属性设置为 True,
              否则设置为 False [默认值]以在指定的 FrameIndex 之前插入 ImageFile
ImageFile  - 将 ImageFile 属性设置为希望添加其 ActiveFrame 的 ImageFile 对象(对于删除则忽略)
FrameIndex - 对于删除,将 FrameIndex 属性设置为希望删除的帧的索引,
                  对于添加,将 FrameIndex 设置为要在其之前插入ImageFile 的帧的索引,否则设置为 0 [默认值]
              以从指定的 ImageFile 追加帧

ARGB

ARGBData -  将 ARGBData 属性设置为表示指定 FrameIndex 的ARGB 数据的 Longs 的矢量(宽度和高度必须匹配)
FrameIndex - 将 FrameIndex 属性设置为希望修改其 ARGB 数据的帧的索引,否则设置为0[默认值]以修改ActiveFrame

Convert

将得到的 ImageFile 转换为指定的类型。
FormatID    - 将 FormatID 属性设置为所需支持的光栅图像格式,当前可选择的格式有 wiaFormatBMP、
                wiaFormatPNG、wiaFormatGIF、wiaFormatJPEG 或 wiaFormatTIFF
Quality    - 对于 JPEG 文件,可将 Quality 属性设置为从 1 到100 [默认值]之间的任何值,以指定 JPEG 压缩的质量
Compression - 对于 TIFF 文件,可将 Compression 属性设置为 CCITT3、CCITT4、RLE 或 Uncompressed 以指定压缩方案,
                否则可设置为 LZW [默认值]

小节

总的来说,在c#中利用Automation Layer中的Filter非常麻烦(要写一堆Object),这些简单的图像处理操作还不如用GDI+来实现。

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

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

WIAAL模型

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

image-thumb49.png(12.37 K)

5/24/2009 7:13:49 AM

image-thumb50.png(15.66 K)

5/24/2009 7:13:49 AM

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

获取Device对象

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

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

  1. Device device = null;
  2. foreach (DeviceInfo info in manager.DeviceInfos)
  3. {
  4. if (info.Type != WiaDeviceType.ScannerDeviceType) continue;
  5. device = info.Connect();
  6. break;
  7. }

复制代码

扫描图像

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

Item item = device.Items[1];

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

  1. CommonDialogClass cdc = new WIA.CommonDialogClass();
  2. ImageFile imageFile = cdc.ShowTransfer(item,
  3. "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}",
  4. true) as ImageFile;
  5. if (imageFile != null)
  6. {
  7. var buffer = imageFile.FileData.get_BinaryData() as byte[];
  8. using (MemoryStream ms = new MemoryStream())
  9. 10.     {
  10. 11.         ms.Write(buffer, 0, buffer.Length);
  11. 12.         pictureBox1.Image = Image.FromStream(ms);
  12. 13.     }

14. }

复制代码

关于ShowTransfer方法

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

image-thumb51.png(18.47 K)

5/24/2009 7:13:49 AM

声明如下:

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})

============================================================================

有人提问

真是好文. wia的sample很多都是vb各c++的. c#的真的很小. 先謝謝樓主.

但小弟有一個問題. 請先看小弟的PROGRAM.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WIA;
using System.IO;

namespace ScanDoc
{
    public partial class Form1 : Form
    {
        String wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}";
        String wiaFormatTIFF = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}";

DeviceManager manager;
        Device device;
        CommonDialogClass cdc;

public Form1()
        {
            InitializeComponent();
            manager = new DeviceManager();
            cdc = new WIA.CommonDialogClass();
            device = cdc.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, true, true);
            manager.RegisterEvent("{6AA1C701-F2FD-11D2-99F9-006008CF3572}", device.DeviceID);
            manager.OnEvent += new _IDeviceManagerEvents_OnEventEventHandler(OnScanImageButtonPress);
        }

private void scanTest()
        {
            ImageFile imageFile = cdc.ShowTransfer(device.Items[1], wiaFormatTIFF, true) as ImageFile;
            displayScanedImage(imageFile);
        }

private void displayScanedImage(ImageFile imageFile)
        {
            if (imageFile != null)
            {
                byte[] buffer;
                buffer = imageFile.FileData.get_BinaryData() as byte[];
                using (MemoryStream ms = new MemoryStream())
                {
                    ms.Write(buffer, 0, buffer.Length);
                    pictureBox1.Image = Image.FromStream(ms);
                }
            }
        }

private void OnScanImageButtonPress(string eventId, string deviceId, string itemId)
        {
            scanTest();
        }

}
}

這程序一開始會請使用者選擇 掃瞄器.
以后每按一下 scan 的鍵就會運行 ScanTest 這個 procedure.
這支程序在一般掃瞄器無什麼問題. 問題是如果我用有送紙器的掃瞄器,問題就出玩. 問題如下:

1.) 掃瞄格式如果是 wiaFormatJPEG. 每按一下掃瞄器上的掃瞄按鈕,就只掃瞄一張.
2.) 掃瞄格式如果是 wiaFormatTIFF. 每按一下掃瞄器上的掃瞄按鈕,可以把送紙器的文件都全掃瞄到一個 多頁的TIFF檔. 但再把文件放回送紙器,再按掃瞄按鈕. 這情況就只會出現 進導條 而掃瞄器則沒有動作.

如果我修改 scanTest() 則可以正常掃瞄. 但會再要求重就選擇掃瞄器.
        private void scanTest()
        {
            device = cdc.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, true, true);
            ImageFile imageFile = cdc.ShowTransfer(device.Items[1], wiaFormatTIFF, true) as ImageFile;
            displayScanedImage(imageFile);
        }

不知是什麼問題.請樓主指教.

============================================================================

在C#中使用WIA获取扫描仪数据(五、注册事件)

好了,现在我们能在c#里通过编程扫描图像了。还不满足?对,在前面的例子里,需要扫描的时候总是要按下一个扫描按钮,既傻又费事。现在的扫描仪,上面往往会多几个额外的按钮用来和用户交互,例如我是用的HP G2410上就有两个按钮:扫描及复制。那么,能不能用这两个按钮来代替程序里的那个难看的按钮呢?

image-thumb52.png(29.40 K)

5/24/2009 7:17:45 AM

注意左上角那个难看的按钮了吗?

在WIAAL里,我们可以同过注册设备事件,监听事件等方式和设备上的按钮交互。

注册事件

还记得我们在上节提到的DeviceManager对象吗?MSDN官方文档描述:

The Microsoft Windows Image Acquisition (WIA) Device Manager is an extension of the Still Image (STI) Event Monitor. The WIA Device Manager provides objects, methods, and interfaces for the following:

  • Installing devices
  • Enumerating devices
  • Querying properties of installed devices
  • Creating device objects
  • Monitoring device events
  • Acquiring images
  • Registering destination applications.

和传统.Net编程不同,WIA的事件,需要先通过DeviceManager的RegisterEvent的方法注册,才能使用。RegisterEvent定义如下:

void RegisterEvent(string EventID, string DeviceID);其中,EventID是事件的GUID,DeviceID是扫描仪的GUID。在类EventID里,WIA定义了几种基本的事件类型,从定义上不难理解这些ID的所代表的具体事件:

  1. public const string wiaEventDeviceConnected = "{A28BBADE-64B6-11D2-A231-00C04FA31809}";
  2. public const string wiaEventDeviceDisconnected = "{143E4E83-6497-11D2-A231-00C04FA31809}";
  3. public const string wiaEventItemCreated = "{4C8F4EF5-E14F-11D2-B326-00C04F68CE61}";
  4. public const string wiaEventItemDeleted = "{1D22A559-E14F-11D2-B326-00C04F68CE61}";
  5. public const string wiaEventScanEmailImage = "{C686DCEE-54F2-419E-9A27-2FC7F2E98F9E}";
  6. public const string wiaEventScanFaxImage = "{C00EB793-8C6E-11D2-977A-0000F87A926F}";
  7. public const string wiaEventScanFilmImage = "{9B2B662C-6185-438C-B68B-E39EE25E71CB}";
  8. public const string wiaEventScanImage = "{A6C5A715-8C6E-11D2-977A-0000F87A926F}";
  9. public const string wiaEventScanImage2 = "{FC4767C1-C8B3-48A2-9CFA-2E90CB3D3590}";

10. public const string wiaEventScanImage3 = "{154E27BE-B617-4653-ACC5-0FD7BD4C65CE}";

11. public const string wiaEventScanImage4 = "{A65B704A-7F3C-4447-A75D-8A26DFCA1FDF}";

12. public const string wiaEventScanOCRImage = "{9D095B89-37D6-4877-AFED-62A297DC6DBE}";

13. public const string wiaEventScanPrintImage = "{B441F425-8C6E-11D2-977A-0000F87A926F}";

复制代码

例如,我们可以使用以下来吗来注册一个事件,并监听它:

  1. manager.RegisterEvent(EventID.wiaEventScanImage, device.DeviceID);
  2. manager.OnEvent += (eventID, deviceID, itemID) =>
  3. {
  4. //…………
  5. }

复制代码

枚举设备事件

如果你向我这般,兴冲冲地在OnEvent里加入扫描处理逻辑,然后按下HP G2410上的扫描按钮,你一定会像我一样,在漫长的等待中渐渐失望:扫描仪根本没有按我所想的那样扫描图片。也就是说,wiaEventScanImage这个事件根本不起作用。

幸好能够通过Device类来枚举设备支持的事件,我写了以下一段代码:

  1. Console.WriteLine("Events:");
  2. foreach (DeviceEvent eve in device.Events)
  3. {
  4. Console.WriteLine("{0}:{1}:{2}", eve.EventID, eve.Name, eve.Description);
  5. }

复制代码

运行后,发现该扫描仪仅仅支持wiaEventDeviceConnected 和 wiaEventDeviceDisconnected ,以及两个HP自定义的事件:按下扫描按钮、按下拷贝按钮。OOXX!

image-thumb53.png(36.57 K)

5/24/2009 7:17:45 AM

按下按钮扫描图像

修改manager.RegisterEvent方法,使用HP提供的EventID:

manager.RegisterEvent("{0C5E2143-FD9B-490B-9AD5-7637A403566B}", device.DeviceID);

最终我们可以通过按下扫描仪上的扫描按钮来扫描数据了!:)

  1. manager.OnEvent += (eventID, deviceID, itemID) =>
  2. {
  3. Item item = device.Items[1];
  4. CommonDialogClass cdc = new WIA.CommonDialogClass();
  5. ImageFile imageFile = cdc.ShowTransfer(item,
  6. "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}",
  7. true) as ImageFile;
  8. 10.     if (imageFile != null)
  9. 11.     {
  10. 12.         var buffer = imageFile.FileData.get_BinaryData() as byte[];
  11. 13.         using (MemoryStream ms = new MemoryStream())
  12. 14.         {
  13. 15.             ms.Write(buffer, 0, buffer.Length);
  14. 16.             pictureBox1.Image = Image.FromStream(ms);
  15. 17.         }
  16. 18.     }

19. };

转载于:https://www.cnblogs.com/zhaoyongjiang/p/8143293.html

在C#中使用WIA获取扫描仪数据相关推荐

  1. 在C#中使用WIA获取扫描仪数据(利用Filter处理图片)

    WIA Automation Layer不仅能从设备中捕获照片,还能进行简单的处理.当WIA Automation Layer从设备中捕获照片,保存为一个ImageFile对象,我们可以通过访问该Im ...

  2. (转) 在C#中使用WIA获取扫描仪数据(三、利用Filter处理图片)

    <script type="text/javascript"></script> <script type="text/javascript ...

  3. 在C#中使用WIA获取扫描仪数据(三、利用Filter处理图片)

    WIA Automation Layer不仅能从设备中捕获照片,还能进行简单的处理.当WIA Automation Layer从设备中捕获照片,保存为一个ImageFile对象,我们可以通过访问该Im ...

  4. 在微信菜单中采用重定向获取用户数据

     C#开发微信门户及应用(14)-在微信菜单中采用重定向获取用户数据 我曾经在系列文章中的<C#开发微信门户及应用(11)--微信菜单的多种表现方式介绍>中介绍了微信菜单里面的重定向操 ...

  5. python通过api获取数据_在一次点击PythonRequests中从API获取所有数据

    import requests url = 'http://www.justdial.com/autosuggest.php?' param = { 'cases':'popular', 'strtl ...

  6. spring中jso文件获取后台数据时注意的点

    在jsp文件的script将后台的数据拼写并展示到页面 var tr = '<tr><td>' + s.baby_id + '</td>';tr += '<t ...

  7. [分享] VBA中使用WIA处理本地图像

    一.WIA简介       (一)关于WIA       WIA是Windows Image Acquisition 的简称,它是 Windows Millennium Edition (Window ...

  8. Python获取股票数据并绘制相应K线图,看这个就够了!

    Python对股票的K线可视化 前言 说明 注意 数据获取 Tushare获取股票数据 获取医疗器械板块数据(代码部分) 获取股票数据(代码部分) 数据预处理 变量中文化(代码部分) K线绘制 代码部 ...

  9. Domino开发使用JAVA,起点R3使用JAVA获取Domino数据(上篇)

    在上篇中介绍了从JAVA中获取Domino数据库中的文档信息,但有一个缺点,就是必须要有本地Notes,即限制了只能在Windows下使用,在有些情况下,可能需要在其他操作系统中通过JAVA获取Dom ...

最新文章

  1. linux驱动:TI+DM8127+GPIO(二)之驱动
  2. Android 布局文件Graphical Layout不显示预览+不能实现拖置功能
  3. Wdatepicker日期控件的使用指南
  4. 成功解决Windows无法启动服务NVIDIA Dispaly Container LS服务(位于本地计算机上),错误2:系统找不到指定的文件
  5. Struts-config.xml配置文件《action-mappings》元素的详解
  6. 求老板放过!我Java8还没用呢,Java14又来了...
  7. 微信聊天可以带话题了 网友:朋友分享安利更方便了
  8. 图像增强处理之:同态滤波与Retinex算法(二)McCann Retinex和McCann99 Retinex迭代算法
  9. session json()中文乱码_[Win] FTP传输工具 FlashFxp v5.4.0 build3970 中文便携版
  10. php搭建mysql连接池
  11. java Web api接入讯飞aiui(1)
  12. 银行账号和身份证号的数据有效性设置
  13. c++刷题(3/100)数独,栈和队列
  14. mysql-8.0.23-winx64安装教程
  15. 红外摄像机应用原理与常见技术问题分析
  16. Netty 学习 之(1)Netty是什么
  17. python道德经摘要
  18. C 基于UDP实现一个简易的聊天室
  19. 炸弹人游戏(DFS||BFS)
  20. ⑧ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 BH1750 光强传感器】

热门文章

  1. System.setOut()重定向输出解释
  2. android中涉及的字体修改
  3. android 手机 跑分榜,Android手机哪家强?安兔兔鲁大师榜单见分晓!
  4. windows 商店的Ubuntu18.04安装教程
  5. 计算机中的科学思维能力指哪三种,浅析计算机应用与科学思维能力培养
  6. facebook广告后台设置
  7. Connection Backoff Interop Test Descriptions
  8. laravel Eloquent whereIn 多个字段
  9. 区块链入门 第二部分
  10. 案例驱动python编程入门-郑州高薪python全栈工程师