隨着掃描儀、數碼相機和其餘圖像採集設備的引入,用戶熱切地發現了將圖像整合到他們的文檔和其餘工做中的價值。然而,支持這種光柵數據的顯示和操做成本很高,應用程序開發人員須要建立用戶界面並內置設備控制各類各樣可用的圖像設備。
一旦他們的應用程序準備好支持給定的設備,他們就會面臨一個使人沮喪的現實:設備不斷地升級新的功能和特性。應用程序開發人員發現他們不斷地修改他們的產品,以保持最新圖像採集設備和軟件應用程序的開發人員都認識到須要圖像設備和應用程序之間的標準通訊。一個標準有利於使用他們產品的用。它將容許更多的應用程序訪問設備供應商的產品,而應用程序供應商能夠訪問來自這些設備的數據,而不須要關心提供這些數據的是哪一種類型的設備或特定的設備。
TWAIN的開發正是出於對一致性和簡化的須要。git
TWAIN定義了一個標準的軟件協議和API(應用程序編程接口),用於在軟件應用程序和圖像採集設備(數據的來源)之間進行通訊。
Twain的三個關鍵要素是:github
關於這幾要素是什麼關係呢?通俗的說就是Twain是一個協議,這個協議不須要咱們本身去實現和設備(我這裏是掃描儀)的通信,這個通信是由一個叫作Data Source Manager的來提供,咱們的應用程序只須要調用Data Source Manager對應的功能,而後由Data Source Manager去負責和支持Twain協議的設備通信(準確的說應該是設備的驅動)。編程
這個Data Source Manager 在windows裏面就是由twain_32.dll實現。windows
Twain協議PDF https://ask.qcloudimg.com/draft/7651952/jhzuki5dnp.pdfapp
TWAIN元素之間的通訊能夠經過兩個入口點實現。他們是DSM_Entry()和DS_Entry()。DSM指數據源管理器(也就是twain_32.dll),DS指數據源(驅動程序)。函數
應用程序的目標是從源獲取數據。可是應用程序不能直接調用源。全部對數據、功能信息、錯誤信息等的請求都必須經過源管理器處理。工具
Twain定義了大約140個操做。應用程序將它們發送到源管理器進行傳輸。應用程序指定哪一個元素(源管理器或源)是每一個請求操做的最終目的地。
應用程序經過源管理器惟一的入口點DSM_Entry()函數與源管理器通訊。DSM_Entry函數的參數列表包含:網站
TW_UINT16 TW_CALLINGSTYLE DSM_Entry ( pTW_IDENTITY pOrigin, // source of message pTW_IDENTITY pDest, // destination of message TW_UINT32 DG, // data group ID: DG_xxxx TW_UINT16 DAT, // data argument type: DAT_xxxx TW_UINT16 MSG, // message ID: MSG_xxxx TW_MEMREF pData // pointer to data );
應用程序、源管理器和源必須通訊來管理數據的獲取。這個過程必須以特定的順序發生,這是合乎邏輯的。例如,在加載源管理器並準備好進行請求通訊以前,應用程序沒法成功地請求來自源的數據傳輸。爲了保證序列的正確執行,TWAIN協議定義了在TWAIN會話中存在的七種狀態。會話是應用程序經過源管理器鏈接到特定源的時間段。
應用程序鏈接到源管理器的期間是一個惟一的會話,Source Manager和Source的TWAIN元素都佔據一個特定的狀態。到新狀態的轉換是由應用程序或源請求的操做引發的,轉換能夠向前或向後進行。大多數轉換都是單狀態轉換。
轉換狀態圖以下:ui
State 1 to 2 -加載source manager 獲取 DSM_Entry接口
State 2 to 3 - 打開source manager
State 3 - 選擇 Source
State 3 to 4 - 打開 Source
State 4 - 設置source的Capabilities
State 4 to 5 - 請求從source獲取數據
State 5 to 6 - 數據能夠準備消息
State 6 to 7 - 開始數據傳輸
State 7 to 6 to 5 - 完成傳輸
State 5 to 1 - 斷開鏈接3d
應用程序調用Source Manager,使用NTwain進行操做,在nuget裏面添加引用。
對應的github地址,裏面有源碼和demo: https://github.com/soukoku/ntwain/tree/v3
添加引用後打開source manager,而後能夠選擇Source 或者加載默認Source。
打開Source後狀態爲4 則咱們能夠對設備進行設置,而設置這些功能存在於許多種類中,但都有默認值、當前值和可能的值
其餘可選的可支持的值。這些種類能夠在協議裏面查到,也就是驅動裏面對應的各類設置。在Twain協議裏面把這些功能叫作Capabilities ,對應的NTwain包裏面也封裝了,好比設置掃描儀雙面掃描
_twain.CurrentSource.Capabilities.CapDuplexEnabled.SetValue(BoolType.True);
這裏有個大坑,在使用NTwain設置的時候經過CapPixelType設置圖像模式只能設置黑白灰度彩色三種,經過以下代碼:
_twain.CurrentSource.Capabilities.ICapPixelType.SetValue(PixelType.RGB)
不能設置多圖輸出,在驅動裏面找看到圖片確實只支持這幾種方式,而後我一直覺得是我看掉了哪一個功能,看完了Twain協議,而後去網上各類找沒有這方面的資料,大部分都是很簡單的介紹,糾結了一週沒有搞清楚。而後搜到vintasoft 這個網站的時候看到一個提問才恍然大悟,原來這個設置Twain標準協議裏面確實沒有這個,我估計是富士通廠家本身搞的一個。由於上面Twain通信過程說了各類操做只能經過DSM_Entry()函數,而且只要你傳入的三元組的( TW_UINT16 DAT,// data argument type: DAT_xxxx) Id正確且支持就好了。
使用以下代碼new一個多圖像輸出功能對象,而後像其它同樣設置便可。
new CapWrapper<MutilImageOutPutType>(dataSource, (CapabilityId)0x80f2, ValueExtensions.ConvertToEnum<MutilImageOutPutType>, value => new TWOneValue { Item = (uint)value, ItemType = ItemType.UInt16 });
public enum MutilImageOutPutType : ushort { Disabled = 0, RGBAndBW = 1, BWAndRGB = 2, Enabled = 3, Auto = 4, }
最後掃描獲取圖片