編輯 | 究查 | 歷程 | 原始

EnScan 的功能打包成 webAssembly 處理 Scan 是否可行

這是一個非常深入的技術架構問題。簡短的回答是:**「直接打包」不可行,但「功能移轉」與「資料對接」是可行的,只是架構需要完全翻轉。**

我們必須從 WebAssembly (Wasm) 的底層本質,來分析為什麼 EnScanDibHandle 無法直接放入 Wasm:


1. 為什麼無法將 EnScan 打包成 WebAssembly 進行「掃描」?

核心障礙:硬體存取與沙盒 (Sandbox) 限制

  • Wasm 的隔離性: WebAssembly 運行在瀏覽器的安全沙盒中。它**完全無法**存取你電腦的硬體(如 USB 接口、掃描機)。它甚至看不到你的 C 槽或 Windows 登錄表。
  • TWAIN 協定限制: EnScan 的核心是封裝 Windows 的 TWAIN API。TWAIN 是一個極度依賴作業系統訊息(Window Messages)與本地驅動程式(.ds 檔案)的協定。Wasm 無法呼叫 Windows API,也無法載入掃描機的 .dll 驅動程式。
  • VCL 與 WinAPI 依賴: EnScan 是一個 VCL 元件,深層綁定了 Windows 的 GDI(圖形設備介面)。Wasm 並沒有 Windows GDI,它只有一塊線性記憶體(Linear Memory)和 Canvas API。

2. Wasm 能處理 DibHandleTMemoryStream 嗎?

這涉及到兩者記憶體模型的完全不相容:

關於 DibHandle (Windows HGLOBAL)

  • 不可行: DibHandle 本質上是一個 Windows 作業系統核心管理的**記憶體地址代號**。
  • 原因: Wasm 的記憶體是「封閉的線性陣列」。它無法透過一個 Windows 句柄(Handle)去讀取 Windows 系統層級的記憶體。如果你把 DibHandle 傳給 Wasm,Wasm 只會把它看作一個無意義的整數。

關於 TMemoryStream

  • 有條件可行: 如果你使用如 TMS WEB Core 這類支援 Delphi 語法轉 Wasm 的工具,它們有實作虛擬的 TMemoryStream
  • 本質差異: * Delphi Win32 的 TMemoryStream:操作的是實體 RAM。
    • Wasm 的 TMemoryStream:操作的是瀏覽器分配給 Wasm 實例的一塊 ArrayBuffer
    • 兩者不通: 你無法直接將 Win32 的記憶體指針直接「丟進」Wasm 的記憶體空間。

3. 可行的「現代化」架構建議:混合模式 (Hybrid)

如果你想用 Wasm 處理掃描後的影像,正確的架構應該是:

第一步:本地端代理 (Local Agent/Service)

你仍需要一個小的 Delphi Win32 程式(或 Service)跑在使用者電腦上:
1. 呼叫 EnScan 進行掃描。
2. 在 OnAcquire 中拿到 DibHandle
3. 關鍵轉化:在本地端將 DibHandle 轉成標準的影像格式(如 Base64 StringUint8Array 二進位流)。

第二步:通訊橋樑

本地程式透過 WebSocketLocal HTTP Server (REST) 將這串二進位資料傳送給瀏覽器。

第三步:Wasm 接收與處理

  1. 瀏覽器收到二進位流。
  2. 將資料寫入 Wasm 的記憶體(ArrayBuffer)。
  3. 這時 Wasm 就可以發揮威力了:你可以用 Wasm 來做影像分析、條碼辨識、或是用 C++/Rust 編譯出來的高效能演算法進行影像優化。

4. 總結對照表

功能特性 原有的 Delphi OCX 現代 WebAssembly 方案
硬體控制 (TWAIN) 直接呼叫 (OK) 無法存取 (需透過本地 Service 轉發)
記憶體管理 使用 Windows Handle (DibHandle) 使用 Wasm 線性記憶體 (ArrayBuffer)
影像處理速度 極快 (Native) 極快 (Wasm 近乎 Native)
跨瀏覽器支援 僅限 IE / Edge IE Mode 全瀏覽器支援 (Chrome, Safari, Edge)
安全風險 高 (ActiveX 有權限漏洞) 極高 (沙盒保護)

我的建議:

不要嘗試把 EnScan 直接「編譯」成 Wasm,那會導致數千個 WinAPI 連結錯誤。

你應該將 CB_IMGPSScanImp.pas 拆分成兩部分:
1. Backend (Win32): 只負責掃描與存成檔案/串流。
2. Frontend (Wasm/Web): 負責顯示 ImageScrollBox 的功能、UI 邏輯與上傳伺服器。

你想了解如何寫一個簡單的 Local Service,讓 Delphi 掃描後把資料傳給網頁嗎? 這通常是目前銀行系統現代化(去 IE 化)最普遍的作法。