C#使用Twain協(xié)議實(shí)現(xiàn)掃描儀連續(xù)掃描功能
C#調(diào)用Twain接口實(shí)現(xiàn)掃描儀連續(xù)掃描。在監(jiān)聽的TwainCommand.TransferReady狀態(tài)中,是調(diào)用掃描儀掃描圖片的。我開始的時(shí)候嘗試修改twain類中TransferPictures的方法,但是結(jié)果證實(shí)不可行。其實(shí)這是一個(gè)誤區(qū),我們只需要修改一下twain的啟動(dòng)掃描事件,可以根據(jù)是否連續(xù)掃描給掃描儀傳不同的參數(shù)以達(dá)到此效果?!≈恍枰恍写a,就可實(shí)現(xiàn)一次掃描多張,且不需要更改掃描儀的任何設(shè)置。
如果用Twain協(xié)議實(shí)現(xiàn)一次掃描多張圖片?相信有接觸過Twain協(xié)議與掃描儀通信的朋友都遇到過這樣的問題。按照網(wǎng)上的例子,在連續(xù)送紙的掃描儀中,調(diào)用一次卻只能掃描一張圖片,怎么破?
關(guān)于這個(gè)問題 我研究了好久,終于在困擾了我7天之后,我搞定了,下面分享一下我的解決經(jīng)驗(yàn)。
新建一個(gè)ScanCommon類,在調(diào)用界面,寫下調(diào)用掃描的方法:
ScanCommon scan = new RS_ScanCommon(fileName, this.Handle); scan.PassDataBetweenForm += new RS_ScanCommon.PassDataBetweenFormHandler(scan_PassDataBetweenForm); //是否連續(xù)掃描 scan.bContinuousScan = true; scan.dtRow = dtRow; this.Enabled = false; scan.StartScan();
在ScanCommon類中,調(diào)用Twain的接口類(Twain類網(wǎng)絡(luò)上可以找到,本文略),主要代碼如下:
// 添加一個(gè)委托 public delegate void PassDataBetweenFormHandler(object sender, PassDataEventArgs e); // 添加一個(gè)PassDataBetweenFormHandler 類型的事件 public event PassDataBetweenFormHandler PassDataBetweenForm; public ScanCommon(string fileName, IntPtr Handle) { this.fileName = fileName; this.Handle = Handle; //掃描初始化(默認(rèn)使用TWAIN方式進(jìn)行連接) tw = new Twain(); tw.Init(Handle, out rc); //tw.Select(); } //啟動(dòng)掃描 public void StartScan() { if (rc != TwRC.Success) { MessageBox.Show("設(shè)備初始化失敗,請(qǐng)檢查硬件及驅(qū)動(dòng)!"); } else { string path = "XXX路徑" + "\\ScannerFile\\" + frmName; if (Scanning(path) == false) { MessageBox.Show("設(shè)備未找到或設(shè)備不支持TWAIN組件,無法自動(dòng)創(chuàng)建掃描任務(wù)。") ; //回調(diào)主窗口 PassDataEventArgs args = new PassDataEventArgs("exit"); PassDataBetweenForm(this, args); GC.Collect(); } } }
在ScanCommon類中,主要的掃描方法均可以通過調(diào)用twain類實(shí)現(xiàn),Scanning是調(diào)用驅(qū)動(dòng)實(shí)現(xiàn)掃描的方法。Application.AddMessageFilter是添加掃描儀的事件監(jiān)聽,在監(jiān)聽事件中返回掃描儀的不同狀態(tài)以實(shí)現(xiàn)取消和掃描的一些操作。
主要代碼如下:
#region 掃描的一些方法 private bool Scanning(string filePath) { if (!msgfilter) { msgfilter = true; Application.AddMessageFilter(this); } ScanPath = filePath; return tw.Acquire(ref strScanErrorMessage, bContinuousScan); } /// <summary> /// 保存圖片 /// </summary> /// <param name="dibhandp"></param> private void ImageSave(IntPtr dibhandp) { bmprect = new Rectangle(0, 0, 0, 0); if (dibhandp != IntPtr.Zero) dibhand = dibhandp; bmpptr = GlobalLock(dibhand); pixptr = GetPixelInfo(bmpptr); } public void EndingScan() { if (msgfilter) { tw.Finish(); RemoveMessageFilter(this); msgfilter = false; } } public static void RemoveMessageFilter(IMessageFilter value) { Application.RemoveMessageFilter(value); } #endregion
在監(jiān)聽的TwainCommand.TransferReady狀態(tài)中,是調(diào)用掃描儀掃描圖片的。我開始的時(shí)候嘗試修改twain類中TransferPictures的方法,但是結(jié)果證實(shí)不可行。
其實(shí)這是一個(gè)誤區(qū),我們只需要修改一下twain的啟動(dòng)掃描事件,可以根據(jù)是否連續(xù)掃描給掃描儀傳不同的參數(shù)以達(dá)到此效果?!?/p>
只需一行代碼,就可實(shí)現(xiàn)一次掃描多張,且不需要更改掃描儀的任何設(shè)置。
如果設(shè)備支持連續(xù)送紙,啟動(dòng)掃描時(shí)掃描儀會(huì)直接連掃直到紙張全部掃完
//此行代碼是連續(xù)掃描 TwCapability cap = new TwCapability(TwCap.XferCount, -1);
代碼如下:
/// <summary> /// 啟動(dòng)掃描 /// </summary> /// <param name="strScanErrorMessage"></param> /// <returns></returns> public bool Acquire(ref string strScanErrorMessage, bool MultiScan) { try { TwRC rc; CloseSrc(); if (appid.Id == IntPtr.Zero) { Init(hwnd, out rc); if (appid.Id == IntPtr.Zero) strScanErrorMessage = "未找到掃描儀設(shè)備,請(qǐng)查看是否安裝掃描儀驅(qū)動(dòng)!"; return false; } rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.OpenDS, srcds); if (rc != TwRC.Success) { strScanErrorMessage = "未找到掃描儀設(shè)備"; return false; } if (MultiScan) { //如果是連續(xù)掃描 TwCapability cap = new TwCapability(TwCap.XferCount, -1); rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap); } else { //否則只掃描一張 TwCapability cap = new TwCapability(TwCap.XferCount, 1); rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap); } if (rc != TwRC.Success) { strScanErrorMessage = "未找到掃描儀設(shè)備"; CloseSrc(); return false; } TwUserInterface guif = new TwUserInterface(); guif.ShowUI = 1; guif.ModalUI = 1; guif.ParentHand = hwnd; rc = DSuserif(appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.EnableDS, guif); if (rc != TwRC.Success) { strScanErrorMessage = "掃描儀中沒有紙"; CloseSrc(); GC.Collect(); return false; } } catch (Exception e) { strScanErrorMessage = e.Message; GC.Collect(); return false; } GC.Collect(); return true; }
掃描結(jié)束后,回調(diào)主窗口返回?cái)?shù)據(jù),主窗口添加如下事件:
private void scan_PassDataBetweenForm(object sender, PassDataEventArgs e) { if (e.EventStr == "exit") { this.Cursor = Cursors.WaitCursor; frm.dtRow = this.dtRow; //處理圖片的一些方法.... this.Enabled = true; this.Cursor = Cursors.Default; GC.Collect(); } }
到此這篇關(guān)于C#使用Twain協(xié)議實(shí)現(xiàn)掃描儀連續(xù)掃描的文章就介紹到這了,更多相關(guān)C#掃描儀連續(xù)掃描內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)現(xiàn)獲取系統(tǒng)目錄并以Tree樹叉顯示的方法
這篇文章主要介紹了C#實(shí)現(xiàn)獲取系統(tǒng)目錄并以Tree樹叉顯示的方法,可以加深讀者對(duì)于C#下數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)方法的認(rèn)識(shí),需要的朋友可以參考下2014-07-07Unity Shader實(shí)現(xiàn)圖形繪制(藍(lán)天白云大海)
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)圖形繪制,藍(lán)天白云大海,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04Unity實(shí)現(xiàn)鼠標(biāo)點(diǎn)2D轉(zhuǎn)3D進(jìn)行旋轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)鼠標(biāo)點(diǎn)2D轉(zhuǎn)3D進(jìn)行旋轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C#中Datetimepicker出現(xiàn)問題的解決方法
這篇文章主要給大家介紹了關(guān)于C#中Datetimepicker出現(xiàn)問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11c#中將uint值轉(zhuǎn)換成int的實(shí)例方法
在本文里小編給大家整理的是關(guān)于c#中將uint值轉(zhuǎn)換成int的實(shí)例方法,需要的朋友們學(xué)習(xí)參考下。2019-08-08C#實(shí)現(xiàn)數(shù)據(jù)去重的方式總結(jié)
這篇文章主要來和大家一起來討論一下關(guān)于C#數(shù)據(jù)去重的常見的幾種方式,每種方法都有其特點(diǎn)和適用場(chǎng)景,感興趣的小伙伴可以了解一下2023-07-07C#實(shí)現(xiàn)集合轉(zhuǎn)換成json格式數(shù)據(jù)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)集合轉(zhuǎn)換成json格式數(shù)據(jù)的方法,涉及C#針對(duì)dataTable、Enumerable及Json格式數(shù)據(jù)的遍歷及轉(zhuǎn)換操作相關(guān)技巧,需要的朋友可以參考下2016-07-07