# 硬體掃描控制模組 (Scanner Controller) 深度分析 在 `CB_IMGPSScanImp.pas` 中,「硬體掃描控制模組」是系統與實體掃描設備溝通的唯一橋樑。它深度依賴 TWAIN 協定(透過第三方元件 `EnScan` 封裝),負責控制硬體行為並將紙本文件轉換為記憶體中的數位影像資料。 若要將此模組進一步細拆,其內部組成可分為以下三大子分類: --- ## 1. TWAIN 介面封裝與控制 (TWAIN Interface Wrapper) **職責**:負責管理實體掃描機的連線狀態、開啟/關閉資料來源 (Data Source),以及觸發掃描動作。 **核心實作特性**: * **掃描機選擇與初始化**: * `SelectScanner` (`scanner.SelectScanner`):呼叫 TWAIN 介面讓使用者選擇預設的掃描機硬體。 * `initkscan` / `CheckScannerConfig`:在系統啟動時檢查掃描機是否已正確配置並支援特定功能(例如檢查 `Scanner.DuplexCap > 0` 確認是否支援雙面掃描)。 * **掃描生命週期管理** (`StatrTwainScan`): * 負責設定 `Scanner.OpenSource`(開啟驅動)。 * 呼叫 `Scanner.AcquireWithSourceOpen` 開始非同步擷取,並傳入回呼函式 (Callback) 的指標與自訂的狀態結構 (`LongInt(@ScanInfo)`)。 * 確保無論掃描成功、失敗或中斷,最終都會安全地執行 `Scanner.CloseSource`。 ## 2. 掃描參數與設定管理器 (Scanner Profile Manager) **職責**:負責載入、維護及套用掃描時所需的各項硬體與前處理參數。這些參數通常從資料庫 (`WORK_INF`) 或是本機的 `FBScan.ini` 中讀取。 **核心實作特性**: * **硬體基本參數 (Hardware Params)**: * `ScanDpi`:解析度設定,對應 `RequestedXDpi` 與 `RequestedYDpi`。 * `ScanColor` (`TImageFormat`):影像色彩模式(黑白 `ifBlackWhite`、灰階 `ifGray256`、彩色 `ifTrueColor`)。 * `ScanDuplex`:控制硬體是否開啟雙面進紙 (`Scanner.Duplex`)。 * `TwainShowUI`:是否顯示掃描機原廠的 TWAIN 設定畫面 (`Scanner.ShowUI`)。 * **硬體增強參數 (Enhancement Params)**: * `ScanBright` (亮度) 與 `ScanContrast` (對比度):當啟用 `ScanImgSetUse` 時,將這些參數直接送入掃描硬體。 * **前置處理規則 (Pre-processing Rules)**: * `DeviceDelete` 與 `DeviceDeleteSize`:定義是否開啟「空白頁自動刪除」以及刪除的位元組閥值。 * `ScannerReverse` (反相)、`ScanDeskew` (硬體/初階去斜)、`BoardClear` (清除黑邊)。 ## 3. 非同步影像接收與初始轉換器 (Acquisition Event Handler) **職責**:做為掃描機與應用程式記憶體的交界點,負責攔截驅動程式傳回的原始記憶體區塊 (`DibHandle`),並進行最基礎的安全轉換與前置判斷。 **核心實作特性** (`OnAcquire` 回呼事件): * **記憶體接管 (Memory Handover)**: * 接收來自 TWAIN 驅動的 `DibHandle`(Device Independent Bitmap 記憶體指標)。 * 利用 `pScanInfo^.Graphic.AssignFromDibHandle(DibHandle)` 將非管理的記憶體轉換為 Delphi VCL 的 `TTiffGraphic` 物件。 * **早階條碼快篩與方向校正 (Early Barcode Detection & Rotation)**: * 為確保後續處理正確,系統會在剛拿到記憶體影像時,立刻進行一次快速的條碼掃描 (`MpsGetBarcode`)。 * 讀取條碼所帶的方向資訊 (`MpsBarcodeinf.r180`),並在記憶體中立刻進行 `Rotate` 旋轉,將顛倒或橫放的文件轉正。 * **基礎裁切與壓縮決策 (Format & Crop Decision)**: * **A3 裁 A4**:呼叫 `CheckNeedCrop` 判斷長寬比例與特定條碼數量,若確認為 A3 合併頁,則立刻在記憶體中將其拆分為 `iGraphic_First` 與 `iGraphic_Sec` 兩張獨立影像。 * **格式與壓縮決策**:針對色彩屬性 (`ifBlackWhite`, `ifTrueColor`, `ifGray256`),決定應該套用哪種壓縮演算法(如黑白套用 `tcGroup4` 或 `tcPackBits`,彩色則轉換為 `tcJpeg` 並套用指定的 `FJpgCompression` 壓縮率)。 --- ## 💡 未來重構與微服務化建議 若要將此「硬體掃描控制模組」進行現代化升級或跨平台轉型,建議考量以下方向: 1. **與 UI 徹底解耦**: 目前的 `OnAcquire` 回呼函式中混雜了大量 UI 操作(如 `ImageScrollBox1.Graphic.Assign(...)`)。應改用「發佈-訂閱模式 (Pub-Sub)」,讓 Scanner Controller 收到影像後只觸發事件,由外部的 UI 層去訂閱並更新畫面。 2. **Web/雲端化架構 (Web TWAIN / WebSockets)**: 若未來系統要走向純 Web 化(捨棄 ActiveX),由於瀏覽器無法直接呼叫 Windows 底層的 TWAIN API,此模組必須被改寫為一隻安裝於 Client 端的 **背景常駐服務 (Local Windows Service / Daemon)**。 該服務可以透過 **WebSocket** 或 **Local REST API** 接收來自網頁端的掃描指令,控制 TWAIN 掃描機,並將接收到的影像轉為 Base64 或二進位流回傳給網頁前端。 3. **單一職責分離 (Separation of Concerns)**: 應將 `OnAcquire` 中厚重的「條碼辨識」、「A3 裁切」與「黑邊處理」移出此模組。Scanner Controller 的唯一職責應該只有:**「將紙本轉為電腦中的 Bitmap」**。後續的處理應交給 `Image Processor` (影像處理模組) 透過管線 (Pipeline) 的方式接手處理。