Twain
隨着掃描儀、數碼相機和其他圖像采集設備的引入,用戶熱切地發現了將圖像整合到他們的文檔和其他工作中的價值。然而,支持這種光柵數據的顯示和操作成本很高,應用程序開發人員需要創建用戶界面並內置設備控制各種各樣可用的圖像設備。
一旦他們的應用程序准備好支持給定的設備,他們就會面臨一個令人沮喪的現實:設備不斷地升級新的功能和特性。應用程序開發人員發現他們不斷地修改他們的產品,以保持最新圖像采集設備和軟件應用程序的開發人員都認識到需要圖像設備和應用程序之間的標准通信。一個標准有利於使用他們產品的用。它將允許更多的應用程序訪問設備供應商的產品,而應用程序供應商可以訪問來自這些設備的數據,而不需要關心提供這些數據的是哪種類型的設備或特定的設備。
TWAIN的開發正是出於對一致性和簡化的需要。
Twain 開發簡介
TWAIN定義了一個標准的軟件協議和API(應用程序編程接口),用於在軟件應用程序和圖像采集設備(數據的來源)之間進行通信。
Twain的三個關鍵要素是:
- Application software
必須修改應用程序才能使用TWAIN。 - Source Manager software
該軟件管理應用程序和源程序之間的交互。這段代碼在TWAIN開發者的工具包中提供,每個TWAIN應用程序和源代碼都應該免費提供。 - Source software
該軟件控制圖像采集設備,由設備開發人員按照TWAIN規范編寫。傳統的設備驅動程序現在包含在源軟件中,不需要由應用程序提供。
關於這幾要素是什么關系呢?通俗的說就是Twain是一個協議,這個協議不需要我們自己去實現和設備(我這里是掃描儀)的通訊,這個通訊是由一個叫做Data Source Manager的來提供,我們的應用程序只需要調用Data Source Manager對應的功能,然后由Data Source Manager去負責和支持Twain協議的設備通訊(准確的說應該是設備的驅動)。
這個Data Source Manager 在windows里面就是由twain_32.dll實現。
Twain協議PDF https://ask.qcloudimg.com/draft/7651952/jhzuki5dnp.pdf
Twain通訊過程
TWAIN元素之間的通信可以通過兩個入口點實現。他們是DSM_Entry()和DS_Entry()。DSM指數據源管理器(也就是twain_32.dll),DS指數據源(驅動程序)。
應用程序的目標是從源獲取數據。但是應用程序不能直接調用源。所有對數據、功能信息、錯誤信息等的請求都必須通過源管理器處理。
Twain定義了大約140個操作。應用程序將它們發送到源管理器進行傳輸。應用程序指定哪個元素(源管理器或源)是每個請求操作的最終目的地。
應用程序通過源管理器唯一的入口點DSM_Entry()函數與源管理器通信。DSM_Entry函數的參數列表包含:
- 一個標識符結構,提供關於發起函數調用的應用程序的信息。
- 請求的目的地(源管理器或源)。
- 描述請求操作的三元組(triplet)。三元組指:
操作的數據組(DG_)
操作的數據參數類型(DAT_)
操作的消息(MSG_) - 函數調用返回一個值(返回碼),指示操作的成功或失敗。
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協議定義了在TWAIN會話中存在的七種狀態。會話是應用程序通過源管理器連接到特定源的時間段。
應用程序連接到源管理器的期間是一個唯一的會話,Source Manager和Source的TWAIN元素都占據一個特定的狀態。到新狀態的轉換是由應用程序或源請求的操作引起的,轉換可以向前或向后進行。大多數轉換都是單狀態轉換。
轉換狀態圖如下:
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 - 斷開連接
C# 調用
應用程序調用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);
關於富士通fujitsu設置圖像模式:多圖像輸出
這里有個大坑,在使用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,
}
最后掃描獲取圖片