应用场景:
主要功能是实现图片上传到服务器,然后保存服务器图片路径到数据库中。为了用户免去找图片的烦恼,所以就加入了扫描仪扫图片的功能。下面是winform小程序原图。
下面我们进入重点。
①首先,要集成Kodak,必须有一个Kodak包。(需要此包的朋友可以评论或者私信我)
②只实现扫描功能的话,只需要在项目中引用红框内的两个程序集就可以啦。
③如果引用不成功的话,就需要手动在电脑中注册一下。
注册方法:Windows PowerShell 注册(Win10)
将文件夹拷到c:\Windows\SysWOW64下面 然后用cmd注册(Win10以下版本)
注册成功的话就是这个样子
④此时我们已经将这两个程序集引用到我们项目中了,我们接下来需要做的就是在项目中生成两个程序集中的控件
下面是生成方法
(1)点击添加选项卡,给它起一个我们通俗易懂的名字 ,比如扫描仪Demo
(2)然后右击我们刚才添加的选项卡,点击选择项>添加COM组件,选择我们刚才引用到项目中的那两个程序集。
(3)这是我们就可以看到集成到我们项目中的控件啦。
这时我们前期准备工作就做完啦,可以写代码啦。
⑤拖动图像扫描控件到项目中,就是这个样子,我们给它起名字叫 ‘Scan_MyScan’,并且添加一个button按钮,以便我们在button按钮的点击事件中调用扫描仪。这里我的按钮就是下图中的
'扫描仪'按钮。
⑥这是我点击事件中的代码段。
private void Btn_StartScan_Click(object sender, EventArgs e)//启动扫描仪{try{//Scan_MyScan.ShowScanNew(true);int iScanFlag = Scan_MyScan.ShowSelectScanner();//选择扫描仪 9233if (iScanFlag != 0){return;}int iOpen = Scan_MyScan.OpenScanner(); //打开扫描仪 ScanConfig(Scan_MyScan, iOpen);//扫描仪配置}catch (Exception){Scan_MyScan.CloseScanner();}}
Scan_MyScan.OpenScanner()函数的作用就是打开扫描仪,它的返回值是一个int类型的值。
ScanConfig(Scan_MyScan, iOpen);//扫描仪配置 ,我把让扫描仪工作的代码都封装在了这个方 法中,下面会给大家展示出来。
这里catch中加入Scan_MyScan.CloseScanner();关闭扫描仪的函数,是为了防止在扫描仪打开后,程序异常导致没有关闭扫描仪,从而导致扫描仪无法正常工作,除非重启扫描仪。
⑦下面就是上面提到的ScanConfig函数。可以看到此函数大概的逻辑就是判断扫描仪是否打开成功,如果打开成功的话就判断扫描仪是否可用,然后给扫描仪指定缓存路径(这里要注意一下,此路径要以/Img结尾,比如我的路径是这样的:"C:\Users\Administrator\Desktop\ScanPicturesCaChe" +“\\Img”,扫描仪扫完图片就会在C:\Users\Administrator\Desktop\ScanPicturesCaChe这个路径下面放置图片。),然后指定扫描仪的文件格式,再指定一下是否多页等其他属性,最后就是通过mysCan.StartScan()这个函数进行扫描啦。扫描完后就可以在刚才指定的文件夹中看到刚扫描得到的图片。大家可以看到在扫描完以后,我在try中的五行代码,这是对图片处理并且赋值给图片展示控件。
#region 配置扫描仪public void ScanConfig(AxScanLibCtl.AxImgScan mysCan, int iOpen)//配置扫描仪{if (iOpen == 0){if (mysCan.ScannerAvailable() == true)//判断扫描仪是否可用 {string pathGen = sScanCachePath;//扫描仪的图片缓存路径//判断缓存路径是否存在,如果不存在的话就根据路径创建文件夹if (!System.IO.Directory.Exists(sScanCachePath)){System.IO.Directory.CreateDirectory(sScanCachePath);//不存在就创建目录 }mysCan.MultiPage = true;//是否多页 mysCan.PageCount += 1;//string paths = pathGen + "//app.path" + "UN";mysCan.Image = pathGen+ "\\Img";mysCan.FileType = FileTypeConstants.BMP_Bitmap;//FileTypeConstants.BMP_Bitmap;//设置文件类型 mysCan.CompressionType = CompressionTypeConstants.JPEG;mysCan.ScanTo = ScanToConstants.DisplayAndUseFileTemplate;mysCan.SetPageTypeCompressionOpts(CompPreferenceConstants.GoodDisplay, ImageTypeConstants.BlackAndWhite1Bit, CompTypeConstants.JPEGCompression, CompInfoConstants.G31DFaxRBO);mysCan.StopScanBox = false;mysCan.ShowSetupBeforeScan = true;//是否在扫描前显示设置界面 mysCan.Show();iOpen = mysCan.StartScan();//开始扫描 如果扫描仪是关闭的,该方法将打开扫描仪并在扫描完毕后重新关闭。 if ( iOpen == 0)//如果扫描仪开启开执行这里{try//将刚扫描出来的图片转换为JPG格式,再展示在图片控件上面{ConvertImg(GetLatestFileTimeInfo(sScanCachePath).FileName, sScanCachePath);//改为JPG格式Image imge = Image.FromFile(GetLatestFileTimeInfo(sScanCachePath).FileName);//找到扫描仪缓存文件夹中最新添加的一个文件路径Bitmap bm = new Bitmap(imge, PicEdit.Width, PicEdit.Height);//通过上面路径找到文件PicEdit.Image = pictureHelper.ZoomImage(bm, PicEdit.Width, PicEdit.Height);//将上面文件赋值到图片控件this.textEdit_PicAddress.Text = GetLatestFileTimeInfo(sScanCachePath).FileName;//mysCan.Image;//并将上面找到的路径赋值给路径文本框}catch {mysCan.CloseScanner(); //关闭扫描仪}//Byte[] filebyte = GetScanFileByte(mysCan.Image);}else//扫描仪未开启成功执行这里{//MessageBox.Show("扫描仪没有正确连接或扫描控件已破坏,请检查!", "系统提示");//控件自带弹框提示,所以注释掉}mysCan.CloseScanner(); //关闭扫描仪}else//如果扫描仪没连接走这里{MessageBox.Show("扫描仪没有正确连接,请重新设置!");}}else if (iOpen == 9219)// 如果扫描仪没连接走这里{MessageBox.Show("系统没有安装扫描仪或扫描仪没有正确连接!", "系统提示");}}#endregion
⑧到这里调用扫描仪就算是结束啦。
总结
大家如果仔细看我给图片展示控件赋值那一段代码的话,不难发现我没有通过文件名获取扫描仪产生的图片,而是通过获取文件夹中最新产生的文件来获取图片的。这呢就是我本次项目中的痛点之一,就是无法指定且获取扫描仪产生的文件名字。痛点之二呢就是无法指定扫描仪的文件格式为我们常规的图片格式,比如Jpg等,它产生的图片是bmp格式的。而且公司系统无法展示此格式的文件,后来我是通过获取到文件然后转换文件格式的方式来解决的。
文章写得比较冗余,大家有需要的凑合看一下。有什么交流的可以评论出来。
大家有兴趣可以去看一下Twain集成扫描仪的方法,可能会灵活一些。这里我用的是kodak。