From 5577f3ba7b9f0319c9b32d7080165207726d1f81 Mon Sep 17 00:00:00 2001
From: curtis <curtis@i-mps.com>
Date: 星期一, 30 三月 2026 14:05:46 +0800
Subject: [PATCH] fix: 更新內部引用方法參照
---
reassemble/mermaid/lfcycle/InitialLanguage.md | 23
reassemble/view/mermaid/ISB1ImageMouseUp.md | 13
scripts/dist/ErrList.pas.image.csv | 5
doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ScannerController.json | 46
reassemble/CB_IMGPSScanImp.docmod.pas | 2
reassemble/mermaid/omr/OMRErrini2List.md | 27
reassemble/view/mermaid/DesableImage.md | 10
reassemble/view/mermaid/ISB1Click.md | 10
scripts/list_image_dependencies.js | 70
reassemble/CB_IMGPSScanImp.fileOp.pas | 14
reassemble/view/mermaid/NextPageBtnClick.md | 12
reassemble/view/mermaid/PM109Click.md | 14
reassemble/view/mermaid/NewScanBtnClick.md | 13
reassemble/view/misc.pas | 54
reassemble/mermaid/omr/DistinctFormCode.md | 34
reassemble/view/mermaid/EnableImage.md | 8
reassemble/view/mermaid/PM604Click.md | 11
reassemble/CB_IMGPSScanImp.omr.pas | 74
doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.BusinessLogic.json | 21
reassemble/scan/mermaid/R_W_Scanini.md | 20
reassemble/img/mermaid/CheckNeedCrop.md | 24
doc/curtis/prompt/scanimpl_analysis/04/scanimpl_reAssemble.md | 2
reassemble/view/mermaid/Initialize.md | 9
reassemble/mermaid/omr/OMRErrini2ListForLog.md | 30
reassemble/view/mermaid/PopupMenu6Popup.md | 14
reassemble/CB_IMGPSScanImp.misc.pas | 2
reassemble/CB_IMGPSScanImp.lfcycle.pas | 2
reassemble/transp/fileClient.pas | 2
reassemble/view/mermaid/DocNoIsExistImg.md | 11
reassemble/view/mermaid/PM601Click.md | 21
reassemble/view/mermaid/ViewMouseMode.md | 9
reassemble/view/mermaid/PM404Click.md | 17
reassemble/mermaid/lfcycle/Timer1Timer.md | 20
reassemble/img/transformer.pas | 8
reassemble/view/mermaid/ActiveFormKeyUp.md | 16
reassemble/view/scrollView.pas | 4
reassemble/view/mermaid/PM110Click.md | 12
reassemble/CB_IMGPSScanImp.prUpload.pas | 6
reassemble/view/mermaid/TransBtnClick.md | 26
scripts/dist/deps.all.csv | 16
reassemble/view/popupMenu.pas | 28
doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.TransportManager.json | 6
reassemble/view/mermaid/PM505Click.md | 10
reassemble/scan/mermaid/GetDefScanIni.md | 37
reassemble/mermaid/omr/OMRErr2ini.md | 18
reassemble/scan/mermaid/PageDone.md | 28
reassemble/view/mermaid/PM507Click.md | 17
iis_image_process.pas | 2712 ++++++++++++++++++++++++++++++++
reassemble/view/mermaid/PM106Click.md | 28
reassemble/view/mermaid/PopupMenu1Popup.md | 19
reassemble/scan/twain.pas | 14
reassemble/view/mermaid/PM104Click.md | 23
reassemble/view/mermaid/SampleScanBtnClick.md | 21
reassemble/mermaid/omr/OMRCheckCase.md | 46
reassemble/view/mermaid/PM108Click.md | 25
reassemble/view/mermaid/AddScanBtnClick.md | 11
scripts/scanimpl_annalysis_json_deps.js | 90 +
reassemble/CB_IMGPSScanImp.api.pas | 6
reassemble/bloc/mermaid/SetUseCase.md | 17
reassemble/view/mermaid/PM102Click.md | 14
reassemble/img/mermaid/GetSiteOMR.md | 43
reassemble/mermaid/lfcycle/DestroyEvent.md | 13
reassemble/view/mermaid/PM605Click.md | 14
doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.UIView.json | 284 +-
reassemble/img/mermaid/ImageReSize_FormID.md | 41
reassemble/view/toolBar.pas | 8
reassemble/scan/mermaid/PageEnd.md | 46
CB_IMGPSScanImp.pas | 3
reassemble/bloc/mermaid/BarCode2FormID.md | 31
reassemble/bloc/mermaid/GetUseCase.md | 17
reassemble/view/mermaid/AddAttFileLBClick.md | 21
reassemble/scan/mermaid/OnAcquire.md | 60
reassemble/mermaid/omr/CheckRule2OMRErrInfo.md | 30
reassemble/view/mermaid/GoViewMode.md | 14
reassemble/view/mermaid/ISB1ImageMouseDown.md | 17
reassemble/view/mermaid/PM401Click.md | 14
reassemble/view/mermaid/PM602Click.md | 20
reassemble/bloc/mermaid/BarCode2CaseID.md | 20
doc/curtis/Image_Processer_Analysis.md | 173 +-
reassemble/view/mermaid/WNoteBtnClick.md | 17
reassemble/view/treeView.pas | 6
reassemble/view/mermaid/DisplayMode.md | 15
reassemble/scan/mermaid/initkscan.md | 28
reassemble/scan/mermaid/StatrTwainScan.md | 44
reassemble/view/mermaid/PM111Click.md | 17
reassemble/view/mermaid/FindISB2View.md | 19
reassemble/view/mermaid/PM101Click.md | 14
scripts/dist/CB_IMGPSScanImp.pas.bk.image.csv | 13
reassemble/view/mermaid/OptionBtnClick.md | 18
reassemble/view/mermaid/PM508Click.md | 20
doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ImageProcessor.json | 30
91 files changed, 4,256 insertions(+), 756 deletions(-)
diff --git a/CB_IMGPSScanImp.pas b/CB_IMGPSScanImp.pas
index b3a848a..f90fcff 100644
--- a/CB_IMGPSScanImp.pas
+++ b/CB_IMGPSScanImp.pas
@@ -1058,10 +1058,9 @@
{$I reassemble/view/listView.pas}
{$I reassemble/view/msger.pas}
{$I reassemble/scan/twain.pas}
-{$I reassemble/img/anchor.pas}
+{$I reassemble/CB_IMGPSScanImp.omr.pas}
{$I reassemble/CB_IMGPSScanImp.api.pas}
{$I reassemble/CB_IMGPSScanImp.listMgr.pas}
-{$I reassemble/CB_IMGPSScanImp.omr.pas}
{$I reassemble/CB_IMGPSScanImp.fileOp.pas}
{$I reassemble/CB_IMGPSScanImp.docq.pas}
{$I reassemble/img/transformer.pas}
diff --git a/doc/curtis/Image_Processer_Analysis.md b/doc/curtis/Image_Processer_Analysis.md
index d51d24b..8c7470f 100644
--- a/doc/curtis/Image_Processer_Analysis.md
+++ b/doc/curtis/Image_Processer_Analysis.md
@@ -1,8 +1,8 @@
# 影像處理與轉換模組 (Image Processor) 深度分析
-在 `CB_IMGPSScanImp.pas.bk` 中,「影像處理與轉換模組」負責在硬體掃描取得原始影像後,以及上傳/顯示之前,對影像進行一系列的強化、分析與格式轉換。這個模組是決定影像品質、檔案大小與後續 OMR 辨識準確率的關鍵。
+在 `CB_IMGPSScanImp.pas.bk` 與 `iis_image_process.pas` 中,「影像處理與轉換模組」負責在硬體掃描取得原始影像後,以及上傳/顯示之前,對影像進行一系列的強化、分析與格式轉換。這個模組是決定影像品質、檔案大小與後續 OMR 辨識準確率的關鍵。
-若要將此模組進一步細拆,其內部組成可分為以下四大子分類:
+根據源碼分析,其內部組成可細拆為以下六大子分類:
---
@@ -10,113 +10,118 @@
**職責**:專責處理影像的空間座標轉換、旋轉、去斜以及裁切,確保最終儲存的影像端正且符合業務規定的尺寸。
**核心實作特性**:
-* **影像去斜與轉正**:
- * `DeskewImg`:透過演算法自動偵測影像傾斜角度並將其校正。
- * `Rotate`:依據條碼辨識出的角度 (`MpsBarcodeinf.r180`) 或使用者手動點擊按鈕 (`SpeedButton14Click` 等),進行 90、180、270 度的旋轉。
+* **影像去斜與轉正 (Deskew & Rotate)**:
+ * `DeskewImg`:透過演算法自動偵測影像傾斜角度並將其校正。支援先以黑白影像偵測角度再套用於彩色影像的優化路徑。
+ * `Rotate`:執行 90、180、270 度的旋轉,可用於條碼方向校正或使用者手動轉向。
+* **幾何校正規範 (Geometric Validation)**:
+ * `GetPosAngle`:計算三個定位點之間的夾角,用以判定影像是否嚴重形變。
+ * `CheckSize`:比對定位點距離與標準長寬,若有巨大落差則記錄並自動執行補償性縮放。
* **影像裁切與分割**:
- * `CheckNeedCrop`:根據影像寬高比與偵測到的條碼數量,判斷是否為需要分割的 A3 雙頁合併影像。
- * `CropImg`:給定 `TRect` 座標,將 A3 影像精準裁切為兩張 A4 (`iGraphic_First`, `iGraphic_sec`)。
+ * `CheckNeedCrop` 與 `CropImg`:針對 A3 雙頁合併影像進行自動分割或特定區域裁切。
* **影像縮放 (Resize)**:
- * `ImageReSize_FormID` / `ImageReSize_tmp`:依據表單定義檔 (`FORM_INF`) 中的長寬設定與尋找到的十字定位點,強制將影像縮放變形至標準尺寸,以利後續的 OMR 座標對位。
- * `DpiResize`:調整影像的 DPI 解析度參數。
+ * `ImageReSize_FormID` / `ImageResize`:依據表單定義或目標解析度強制縮放影像,確保 OMR 座標對位精準。
## 2. 色彩處理與編碼轉換器 (Color & Format Converter)
-**職責**:處理影像的色彩深度 (位元深度) 轉換,以及針對不同色彩模式套用最適合的檔案壓縮演算法,以達到最佳的畫質與檔案大小平衡。
+**職責**:處理影像色彩深度轉換,套用最適合的壓縮演算法,並進行濾鏡強化以提升辨識率。
**核心實作特性**:
-* **色彩空間轉換**:
- * `ConvertToBW`:將彩色或灰階影像強制二值化 (Binarization) 轉為黑白影像,這不僅能大幅縮小檔案,也是條碼與 OMR 辨識的必要前置步驟 (系統通常會保留一個隱藏的 `ISB_BW` 物件專做辨識用)。
- * `ConvertToGray`:將彩色轉換為灰階 (`ifGray256`)。
- * `Image_Smooth` / `NegativeImg` / `CleanupBorder`:影像平滑化、反相處理與清除黑邊。
-* **格式與壓縮決策**:
- * 針對黑白影像 (`ifBlackWhite`):使用 `tcGroup4` (CCITT Group 4 Fax Compression) 或 `tcPackBits` 壓縮,並儲存為 `.tif`。
- * 針對彩色/灰階影像 (`ifTrueColor`, `ifGray256`, `ifColor256`):轉換為 `TJpegGraphic`,套用 `tcJpeg` 壓縮與指定的壓縮率 (`FJpgCompression` / `SaveQuality`),並儲存為 `.jpg`。
+* **先進二值化 (Advanced Binarization)**:
+ * `ConvertToBW`:標準二值化處理。
+ * `Gray2BW_RTS` / `Color2BW_RTS`:整合 VRS (Virtual ReScan) 技術,透過特定參數精細化灰階轉黑白的過程,保留關鍵特徵。
+* **影像增強濾鏡**:
+ * `Image_Smooth`(平滑)、`Emboss`(浮雕)、`BrightnessImg`(亮度調整)。
+ * `FilterColor`:濾掉特定顏色(如紅字或背景色)僅保留黑白內容。
+ * `CleanupBorder`:自動清除影像邊緣的掃描黑邊。
## 3. 條碼識別與解析器 (Barcode Recognizer)
-**職責**:獨立負責掃描與解析影像上的一維或二維條碼,這是系統實現「文件自動歸類」的核心依賴。
+**職責**:獨立負責解析影像上的一維或二維條碼,實現「文件自動歸類」。
**核心實作特性**:
-* **條碼引擎呼叫**:
- * `MpsGetBarcode`:呼叫底層的 MPS Barcode 引擎,傳入二值化的影像 (`ISB_BW.Graphic`)。
- * 回傳 `TMpsBarcodeinf` 結構,包含條碼內容字串陣列 (`Text`) 與每個條碼的方向資訊 (`r180`)。
-* **應用與邏輯綁定**:
- * 透過條碼字串找出對應的 `FormID` 與 `DocNo`。
- * 檢查條碼長度是否符合規範 (`FormIDLength`),過濾雜訊或誤判的條碼。
+* **條碼引擎調用**:
+ * `MpsGetBarcode`:呼叫底層引擎解析二值化影像。
+ * `PrintBarcode`:反向操作,將文字轉換為 Code39 條碼並繪製於影像上。
+* **邏輯綁定**:根據條碼字串自動關聯 `FormID` 與 `DocNo`。
-## 4. OMR 與十字定位點分析器 (OMR & Anchor Analyzer)
+## 4. OMR 與定位分析引擎 (OMR & Anchor Analyzer)
-**職責**:專門為「光學標記辨識 (OMR)」服務,負責找出影像上的基準定位點,並計算特定區域內的黑白像素分佈。
+**職責**:為光學標記辨識服務,尋找基準點並計算像素分佈。
**核心實作特性**:
-* **基準點尋找 (Anchor Finding)**:
- * `FindPoint`:根據 XML 定義的模式 (`ANCHOR` 或 `FRAME`),在影像四個角落尋找定位基準點 (`UpLPoint`, `UpRPoint`, `DownLPoint`, `DownRPoint`)。
- * `CheckSize`:比對找到的定位點距離與標準長寬是否有巨大落差,若找不到則記錄至 `AnchorError.dat`。
-* **像素計算與標記判定 (Pixel Calculation)**:
- * `GetSiteOMR`:根據 XML 傳入的相對座標字串 (`Site`),將其換算為實際的 `TRect`。
- * `Get_OMR`:計算該區域內黑色像素的數量。
- * 結合雜訊過濾 (`ClearLine`) 與容差值 (`SafePixel`, `bt`),最終判定該 OMR 欄位是否「有畫記」。
+* **基準點偵測 (Anchor & Spot Detection)**:
+ * `FindPoint`:支援 `ANCHOR` (十字) 或 `FRAME` (框線) 定位模式。
+ * `FindBlackPoint` / `GetBlackSpots`:在指定邊界內搜尋特定比例的黑塊作為定位參考。
+* **像素判定**:
+ * `Get_OMR`:計算區域內黑色像素數量。
+ * `GetPixBW`:底層像素層級的黑白狀態讀取。
+
+## 5. 影像合成與標記引擎 (Image Synthesis & Annotation) —— [NEW]
+
+**職責**:在影像上疊加業務資訊,或自動生成業務用的單據影像。
+**核心實作特性**:
+* **動態浮水印 (Watermark)**:
+ * `Watermark1_Hong`:支援透明度、自定義文字與旋轉(如斜向 330 度)的水印疊加。
+* **業務戳記與單據生成**:
+ * `CreateStamp`:產生包含 UserID 與日期的電子圓戳記。
+ * `CreateNote` / `CreateDraft`:產生空白的便條或草稿圖層。
+ * `CreateReportImg_JSON`:根據 JSON 資料自動合成補件清單影像,整合背景、條碼與文字內容。
+
+## 6. UI 互動輔助與元數據管理 (UI & Metadata) —— [NEW]
+
+**職責**:處理視窗介面上的標記、框選,以及影像檔案內部的隱藏資訊。
+**核心實作特性**:
+* **互動標記**:
+ * `ShowKeyinRect` / `SetKeyinRect_New`:在畫面上動態顯示黃色或透明遮罩,引導人員登打特定欄位。
+ * `GetSelectRect2String`:將人員在 UI 上拖曳的框選區域轉換為公分單位。
+* **元數據處理**:
+ * `GetTag` / `SetTag`:利用 Tiff 檔案的 `ImageDescriptionTag` 儲存自定義業務資訊。
+ * `JpgReSize_Exif`:在處理 JPG 影像時保留或讀取拍攝日期等 EXIF 資訊。
---
-
## 影像相關關鍵字:
```js
[
-'TTiffGraphic',
-'TDibGraphic',
-'DeskewImg',
-'Rotate',
-'CropImg',
-'ImageReSize_FormID',
-'ImageReSize_tmp',
-'CheckNeedCrop',
-'ImageProcessor.transformer',
-'ConvertToBW',
-'ConvertToGray',
-'Image_Smooth',
-'NegativeImg',
-'CleanupBorder',
-'ImageProcessor.converter',
-'MpsGetBarcode',
-'Get_OMR',
-'ImageProcessor.barcodeRecognizer',
-'FindPoint',
+'BrightnessImg',
'CheckSize',
-'GetSiteOMR',
-'ImageProcessor.anchorAnalyzer',
-'TJpegGraphic',
-'DpiResize',
-// 以下可省
-'SaveQuality',
-'FJpgCompression',
-'ifTrueColor',
-'ifGray256',
+'CleanupBorder',
+'Color2BW_RTS',
'ConvertToBW',
'ConvertToGray',
+'CreateReportImg_JSON',
+'CreateStamp',
+'CropImg',
+'DeskewImg',
+'DpiResize',
+'FilterColor',
+'FindBlackPoint',
+'FindPoint',
+'GetBlackSpots',
+'GetSelectRect2String',
+'GetTag',
+'Get_OMR',
+'Gray2BW_RTS',
+'ImageResize',
'Image_Smooth',
-'NegativeImg',
-'CleanupBorder',
-'ifBlackWhite',
-'tcGroup4',
-'tcPackBits',
-'tcJpeg',
-'ifColor25'
+'JpgReSize_Exif',
+'MpsGetBarcode',
+'PrintBarcode',
+'Rotate',
+'SetTag',
+'ShowKeyinRect',
+'TDibGraphic',
+'TJpegGraphic',
+'TNBCleanupBorderTransform',
+'TTiffGraphic',
+'TWatermarkTransform',
+'Watermark1_Hong',
]
```
-
## 💡 未來重構與微服務化建議
-若要對此影像處理模組進行重構,建議方向如下:
-
-1. **抽離為獨立的 Pipeline 模式 (管線模式)**:
- 目前這些功能散落在 `OnAcquire` 與各個事件中。應將其重構為一條清晰的影像處理管線:`Image -> Deskew -> Crop -> ConvertBW -> BarcodeRead -> Resize -> Compress -> Save`。每個步驟 (Step) 應該是獨立的類別,方便抽換或開關。
-2. **解耦 UI 與影像處理**:
- 目前大量依賴畫面上隱藏的 `ISB_BW` (TImageScrollBox) 來進行二值化和條碼辨識。這違反了 MVC 原則且耗費額外的 GDI 資源。應改用純記憶體物件 (如獨立的 `TDibGraphic` 或 `TBitmap`) 在背景執行緒中進行這些運算,不要綁定可見的 UI 元件。
-3. **引入更現代的影像引擎 (如 OpenCV)**:
- 早期依賴的 Envision SDK 在尋找十字定位點 (FindPoint) 和去斜 (DeskewImg) 的演算法可能較為老舊。若未來轉型為微服務架構,可將這部分邏輯移植為 Python/C++ 並使用 OpenCV 來達成更精準的高速運算。
-
-
-
-
-
-
+1. **抽離為獨立的 Pipeline 模式**:
+ 應將影像處理流程標準化:`Image -> PreProcess -> Recognize -> Synthesize -> Output`。
+2. **Web 化對策**:
+ * **Canvas 合成**:影像合成(水印、戳記)功能可轉移至瀏覽器端的 Canvas API 實作。
+ * **影像處理庫**:OpenCV.js 可用於處理去斜與 OMR 偵測;EXIF.js 用於處理照片元數據。
+3. **解耦 UI 與影像處理**:
+ 避免依賴 `TImageScrollBox` 等 UI 元件進行二值化運算。改用純記憶體物件處理,以利於在 Web Worker 中平行運算。
diff --git a/doc/curtis/prompt/scanimpl_analysis/04/scanimpl_reAssemble.md b/doc/curtis/prompt/scanimpl_analysis/04/scanimpl_reAssemble.md
index 8962c2e..c6c2f6a 100644
--- a/doc/curtis/prompt/scanimpl_analysis/04/scanimpl_reAssemble.md
+++ b/doc/curtis/prompt/scanimpl_analysis/04/scanimpl_reAssemble.md
@@ -33,6 +33,8 @@
- ImageProcessor.converter: {{output_path}}/img/converter.pas
- ImageProcessor.anchorAnalyzer: {{output_path}}/img/anchor.pas
- ImageProcessor.payloadArchiver: {{output_path}}/img/imgArchiver.pas
+- ImageProcessor.annotation: {{output_path}}/img/annotation.pas
+- ImageProcessor.metadata: {{output_path}}/img/metadata.pas
##### 0.5.1.4 tags:BusinessLogic 拆分檔案對應
diff --git a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.BusinessLogic.json b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.BusinessLogic.json
index 47f441d..cff2780 100644
--- a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.BusinessLogic.json
+++ b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.BusinessLogic.json
@@ -102,7 +102,7 @@
],
"lIndex": "5907",
"rIndex": "5946",
- "description": "向伺服器請求 LASTEST_FORM_INF 最新表單版本資訊(模式 7)。方法會獲取各文件編號對應的最新表單 ID 與版本號,並儲存於 LASTEST_FORM_INF_List。此資訊用於確保使用者掃瞄的是最新版表單,或是用於舊案件轉檔時的版本對照。"
+ "description": "向伺服器請求 LASTEST_FORM_INF 最新表單版本資訊(模式 7)。方法會獲取各文件編號對應的最新表單 ID 與版本號,並儲存於 LASTEST_FORM_INF_List。此資訊用於確保使用者掃瞄的是最新版表單,或是用於舊案件轉檔時與歷史版本對照。"
},
{
"matcher": "Function TCB_IMGPSScanX.DeleteDocNoFileForESCAN(Path,DocNo:String):Boolean; //刪除指定DocNo文件",
@@ -113,8 +113,8 @@
],
"deps": [
"DeleteDocNoFile",
- "SaveToFile",
"LoadFromFile",
+ "SaveToFile",
"_DelTree"
],
"lIndex": "6141",
@@ -199,11 +199,11 @@
"舊案/異動件處理"
],
"deps": [
- "LoadFromFile",
"FileExists",
+ "LoadFromFile",
+ "MoveFile",
"RenameFile",
- "SaveToFile",
- "MoveFile"
+ "SaveToFile"
],
"lIndex": "10525",
"rIndex": "10574",
@@ -275,11 +275,12 @@
"OMR 檢核"
],
"deps": [
- "ImageReSize_FormID",
- "GetSiteOMR",
- "FindPoint",
- "LoadFromFile",
"FileExists",
+ "FindPoint",
+ "GetSiteOMR",
+ "ImageReSize_FormID",
+ "ImageResize",
+ "LoadFromFile",
"SaveToFile"
],
"lIndex": "12255",
@@ -360,4 +361,4 @@
"rIndex": "14121",
"description": "產生案件內自訂文件的彙總資訊字串。方法專門處理代碼開頭為 'ZZZZZ' 的文件目錄,透過 GetCustomDocName 取得使用者定義的文件名稱,並彙整其總份數、總頁數與編輯異動狀態。最終格式與標準文件一致,但首位欄位改為顯示自訂名稱,確保自訂類別的文件也能正確被伺服器識別與儲存。"
}
-]
+]
\ No newline at end of file
diff --git a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ImageProcessor.json b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ImageProcessor.json
index 7664ad8..6b81b10 100644
--- a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ImageProcessor.json
+++ b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ImageProcessor.json
@@ -7,14 +7,14 @@
"OMR 檢核"
],
"deps": [
- "GetSiteOMR",
"FindPoint",
+ "GetSiteOMR",
"Get_OMR",
"LoadFromFile"
],
"lIndex": "5173",
"rIndex": "5227",
- "description": "在指定影像文件的特定座標執行 OMR (光學標記辨識)。核心邏輯包含:1. 檢查並載入影像檔(若尚未載入),並呼叫 ClearLine 初始化黑白緩衝區。2. 讀取影像的 DPI 與寬高資訊。3. 使用 CM_Str2Rect 將 Site 字串轉為 TRect 矩陣,並參考定位點 (UpLPoint) 進行位移計算。4. 限制辨識區域座標不超出影像邊界。5. 呼叫 Get_OMR 對黑白圖形緩衝區執行辨識並返回結果值(通常為 1 或 0)。此方法是自動化資料檢核的重要工具。"
+ "description": "在影像指定座標執行 OMR 辨識。載入影像、計算相對於定位點的座標偏移、限制邊界並呼叫核心辨識程式獲取結果。"
},
{
"matcher": "Procedure TCB_IMGPSScanX.ImageReSize_FormID(CaseID,FileName:String); //依十字定位點做縮放",
@@ -24,17 +24,18 @@
"影像處理"
],
"deps": [
- "ImageReSize_FormID",
- "FindPoint",
"CheckSize",
- "LoadFromFile",
- "SaveToFile",
"FileExists",
- "LoadFileGetMD5"
+ "FindPoint",
+ "ImageReSize_FormID",
+ "ImageResize",
+ "LoadFileGetMD5",
+ "LoadFromFile",
+ "SaveToFile"
],
"lIndex": "6343",
"rIndex": "6420",
- "description": "根據表單的十字定位點或邊框 (ANCHOR/FRAME) 對掃瞄影像進行縮放調整。流程如下:1. 從 FORM_INF_List 取得表單預設高寬與定位類型。2. 載入對應案件下的影像檔,若為補件模式則跳過原有圖檔。3. 呼叫 FindPoint 尋找影像中的十字線或邊框。4. 呼叫 CheckSize 計算偏移與縮放比例。5. 呼叫 ImageResize 執行實際調整。6. 成功縮放後,記錄檔案 MD5 並儲存更新後的影像,同時將操作記錄寫入 ReSize.dat;若定位點遺失或辨識錯誤,則記錄於 AnchorError.dat。"
+ "description": "依據定位點縮放影像。查詢表單規格,載入影像(過濾補件模式),尋找十字線或邊框定位點,執行縮放並紀錄 MD5 與日誌。"
},
{
"matcher": "Procedure TCB_IMGPSScanX.ImageReSize_tmp(FormID,FileName:String); //依十字定位點做縮放(暫存檔)",
@@ -44,14 +45,15 @@
"影像處理"
],
"deps": [
- "ImageReSize_tmp",
"CheckSize",
+ "ImageReSize_tmp",
+ "ImageResize",
"LoadFromFile",
"SaveToFile"
],
"lIndex": "6421",
"rIndex": "6446",
- "description": "針對暫存影像檔案執行十字定位點縮放處理。此方法是 ImageReSize_FormID 的簡化版本,主要針對暫存檔 (FileName) 與指定的 FormID。邏輯包含從資料庫清單查詢表單尺寸與定位模式,若符合 ANCHOR 或 FRAME 類型,則載入影像並呼叫 CheckSize 檢查是否需要調整。若偵測到影像存在偏移或比例差異(SizeStr 非空),則將調整後的影像直接覆蓋儲存回原始路徑。"
+ "description": "針對暫存檔執行定位點縮放。簡化版 Resize 邏輯,若偵測到尺寸偏移則直接覆蓋原始檔案,用於處理臨時影像。"
},
{
"matcher": "Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //是否是A3要切影像",
@@ -61,11 +63,11 @@
"影像處理"
],
"deps": [
- "TDibGraphic",
- "CheckNeedCrop"
+ "CheckNeedCrop",
+ "TDibGraphic"
],
"lIndex": "9996",
"rIndex": "10021",
- "description": "判斷掃瞄影像是否為 A3 尺寸並需要進行切割(Crop)。判定邏輯有二:首先,檢查影像寬度是否大於 4 倍的 DPI 閥值,藉此初步判斷為大尺寸掃瞄件;其次,遍歷目前的條碼清單 (MpsBarcodeinf),統計有效的表單代碼 (FormID) 數量。如果影像寬度達標且有效表單數量正好為 2,則返回 True。這代表此張大圖實際上是由兩份 A4 表單併排掃瞄而成,後續需依此旗標進行影像分割處理。"
+ "description": "判斷影像是否需執行 A3 切割。依據影像寬度(大於 4 倍 DPI)及條碼清單中有效表單代碼的數量(需為 2 個)作為判定據。"
}
-]
+]
\ No newline at end of file
diff --git a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ScannerController.json b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ScannerController.json
index dcae3f1..2a94a7f 100644
--- a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ScannerController.json
+++ b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.ScannerController.json
@@ -7,17 +7,17 @@
"掃描相關"
],
"deps": [
- "TTiffGraphic",
- "StatrTwainScan",
- "Scanner",
- "Scanner.OpenSource",
- "Scanner.CloseSource",
"OnAcquire",
- "Scanner.AcquireWithSourceOpen"
+ "Scanner",
+ "Scanner.AcquireWithSourceOpen",
+ "Scanner.CloseSource",
+ "Scanner.OpenSource",
+ "StatrTwainScan",
+ "TTiffGraphic"
],
"lIndex": "4390",
"rIndex": "4443",
- "description": "啟動 TWAIN 掃瞄流程。此方法首先檢查掃瞄器驅動是否已安裝,接著初始化 ScanInfo 結構並設定掃瞄參數(如 DPI、影像格式、是否顯示 UI、雙面掃瞄模式、亮度與對比)。流程中會開啟掃瞄來源,呼叫 AcquireWithSourceOpen 執行實際掃瞄作業,並利用 try...finally 確保不論掃瞄成功與否,最終都會關閉掃瞄來源並釋放資源。"
+ "description": "啟動 TWAIN 掃描流程。檢查驅動是否安裝,初始化 ScanInfo 並設定 DPI、影像格式、UI 顯示及雙面掃描模式。執行 AcquireWithSourceOpen 並利用 try...finally 確保資源釋放。"
},
{
"matcher": "procedure TCB_IMGPSScanX.OnAcquire( const DibHandle : THandle;",
@@ -27,13 +27,13 @@
"掃描相關"
],
"deps": [
- "TTiffGraphic",
+ "OnAcquire",
"TJpegGraphic",
- "OnAcquire"
+ "TTiffGraphic"
],
"lIndex": "4444",
"rIndex": "4683",
- "description": "掃瞄影像獲取後的回呼處理函數。核心邏輯包含:1. 將獲取的 DIB 句柄轉為影像對象並設定 DPI。2. 依影像格式執行對應處理:黑白影像會進行條碼辨識、依條碼角度旋轉、影像反向、傾斜矯正及清黑邊;全彩或灰階影像則設定 JPEG 壓縮品質。3. 檢查是否需要進行 A3 切割為 A4 的處理。4. 透過 Deletepage 檢查並過濾空白頁(依據檔案大小)。5. 對於有效影像,更新 UI 顯示並呼叫 PageEnd 決定儲存路徑與檔名,最後依副檔名儲存為 TIFF 或 JPEG 並呼叫 PageDone 完成頁面流程。"
+ "description": "掃描影像獲取後的回調處理。處理 DIB 句柄、設定 DPI、執行條碼辨識、影像旋轉、反向、去偏斜及清黑邊。支援 A3 裁切判定與空白頁過濾。"
},
{
"matcher": "procedure TCB_IMGPSScanX.PageDone;",
@@ -48,7 +48,7 @@
],
"lIndex": "4684",
"rIndex": "4733",
- "description": "完成單頁影像處理後的 UI 更新邏輯。此方法會遞增掃瞄影像總計數,並根據目前的掃瞄模式(新建、取代、插入或取樣)將儲存好的影像檔載入到對應的 ImageScrollBox 元件中。在新建模式下,還會根據 ScanImgShowMode 設定決定影像顯示的品質(反鋸齒開啟與否)與縮放模式(zmFittopage),確保使用者能即時預覽掃瞄結果。"
+ "description": "單頁影像處理後的 UI 更新。累加計數,根據模式(新建、取代、插入、取樣)將影像載入對應的顯示元件,並依設定調整反鋸齒與縮放。"
},
{
"matcher": "procedure TCB_IMGPSScanX.PageEnd;",
@@ -58,16 +58,16 @@
"掃描相關"
],
"deps": [
- "GetNoNameCase",
"DirectoryExists",
- "_DelTree",
- "Str2Dir",
+ "GetNoNameCase",
+ "PageEnd",
"SaveToFile",
- "PageEnd"
+ "Str2Dir",
+ "_DelTree"
],
"lIndex": "4734",
"rIndex": "4950",
- "description": "管理掃瞄影像的儲存路徑與檔案命名規則。主要邏輯如下:1. 辨識條碼以取得 FormID,並判斷是否為導引頁或分案頁。2. 若偵測到分案頁,會重置計數並嘗試取得新的案件編號(CaseID)。3. 確定儲存目錄,包含處理「分份數」邏輯(依 DocNoNeedDiv 決定是否建立新子目錄)。4. 根據目前頁數與 FormID 產生標準化的檔名(如補零序號_FormID.tif)。5. 更新 ContextList(影像索引資訊)並在掃瞄新案件時更新 TreeView UI 結構。此方法確保每張影像都能正確歸類到對應的案件與文件目錄下。"
+ "description": "管理影像儲存路徑與命名。辨識條碼區分表單、導引頁或分案頁;處理分份邏輯與自動建立目錄,並更新樹狀結構索引。"
},
{
"matcher": "Procedure TCB_IMGPSScanX.R_W_Scanini(Mode:Char); //'R'讀取;'W'寫入",
@@ -81,7 +81,7 @@
],
"lIndex": "5254",
"rIndex": "5295",
- "description": "讀取或寫入掃瞄設定檔(FBScan.ini)。此方法使用 Tinifile 物件處理掃瞄相關參數的 I/O 作業。當 Mode 為 'R' 時,從設定檔讀取包含空白頁刪除設定、影像反向、清黑邊、旋轉角度、傾斜矯正、亮度對比以及 UI 顯示模式等參數;當 Mode 為 'W' 時,則將目前的系統變數值回寫至設定檔中,以利下次啟動時恢復使用者的個性化設定。"
+ "description": "讀取或寫入 FBScan.ini。處理包含空白頁刪除、影像反向、清黑邊、旋轉、去偏斜、亮度對比及顯示模式等掃描參數。"
},
{
"matcher": "Procedure TCB_IMGPSScanX.GetDefScanIni; //取得掃瞄的預設值",
@@ -91,13 +91,13 @@
"掃描相關"
],
"deps": [
- "Rotate",
"FJpgCompression",
+ "Rotate",
"Scanner"
],
"lIndex": "5296",
"rIndex": "5472",
- "description": "從資料庫參數清單(WORK_INF_List)初始化並設定掃瞄的系統預設值。流程首先設定一組程式內建的預設數值,隨後遍歷 WORK_INF_List 並比對 PARA_NO 關鍵字,動態更新包含:空白頁判斷大小、影像是否反相、清黑邊、掃瞄 DPI、雙面掃瞄開啟、影像旋轉角度、傾斜矯正、亮度對比、影像儲存路徑、導引頁與分案頁代碼列表、以及 JPEG 壓縮品質等關鍵參數。這使得掃瞄行為可以透過後台設定進行彈性調整。"
+ "description": "從資料庫參數清單初始化掃描預設值。設定 DPI、雙面模式、旋轉角度、路徑、導引頁及分案頁代碼等關鍵系統變數。"
},
{
"matcher": "procedure TCB_IMGPSScanX.initkscan;",
@@ -106,13 +106,13 @@
"ScannerController.twainWrapper"
],
"deps": [
- "initkscan",
"Scanner",
+ "Scanner.CloseSource",
"Scanner.OpenSource",
- "Scanner.CloseSource"
+ "initkscan"
],
"lIndex": "9242",
"rIndex": "9262",
- "description": "初始化並偵測掃瞄器硬體能力。此方法會先將雙面掃瞄勾選框(ScanDuplexCB)設為停用,接著嘗試開啟掃瞄來源(OpenSource),檢查掃瞄器是否支援雙面掃瞄功能(DuplexCap > 0)。如果硬體支援,則啟用 UI 上的勾選框供使用者選擇。最後確保關閉掃瞄來源,若過程中發生異常,會呼叫 DataLoading(False,True) 停止載入狀態提示。"
+ "description": "偵測掃描器硬體能力。嘗試開啟掃描來源以檢查是否支援雙面掃描 (DuplexCap),並據此啟用 UI 控制項。"
}
-]
+]
\ No newline at end of file
diff --git a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.TransportManager.json b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.TransportManager.json
index dfa24ab..11be4f7 100644
--- a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.TransportManager.json
+++ b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.TransportManager.json
@@ -73,8 +73,8 @@
"FTP 相關"
],
"deps": [
- "SetFtpInfo",
- "IIS_Ftp"
+ "IIS_Ftp",
+ "SetFtpInfo"
],
"lIndex": "11042",
"rIndex": "11071",
@@ -95,4 +95,4 @@
"rIndex": "11094",
"description": "通知後台伺服器 FTP 案件上傳已完成。方法會將包含案件狀態的上傳數據發送至特定的 Servlet 介面。邏輯包含檢查 HTTP 通訊是否成功、解析伺服器回傳的結果代碼,並處理可能的登入過期(Session Timeout)情況。若執行失敗,會將錯誤原因記錄至 HttpErrStr,供後續 UI 顯示錯誤訊息。"
}
-]
+]
\ No newline at end of file
diff --git a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.UIView.json b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.UIView.json
index 74424ce..1c13a26 100644
--- a/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.UIView.json
+++ b/doc/curtis/prompt/scanimpl_analysis/scanimpl_annalysis.UIView.json
@@ -147,8 +147,8 @@
"其他內部"
],
"deps": [
- "LoadFromFile",
- "LoadFileGetMD5"
+ "LoadFileGetMD5",
+ "LoadFromFile"
],
"lIndex": "1338",
"rIndex": "1362",
@@ -231,9 +231,9 @@
"UIView.scrollView"
],
"deps": [
- "TJpegGraphic",
"SaveQuality",
- "SaveToFile"
+ "SaveToFile",
+ "TJpegGraphic"
],
"lIndex": "1490",
"rIndex": "1524",
@@ -1017,12 +1017,12 @@
"UIView.popupMenu"
],
"deps": [
+ "FileExists",
"GetNoNameCase",
- "Str2Dir",
+ "LoadFromFile",
"RenameFile",
"SaveToFile",
- "FileExists",
- "LoadFromFile"
+ "Str2Dir"
],
"lIndex": "1925",
"rIndex": "1978",
@@ -1068,14 +1068,14 @@
"UIView.popupMenu"
],
"deps": [
+ "CopyFile",
+ "DeleteImageFile",
+ "DirectoryExists",
"FileExists",
"LoadFromFile",
- "DirectoryExists",
- "CopyFile",
- "SaveToFile",
- "DeleteImageFile",
+ "ReSortFileName",
"RenameFile",
- "ReSortFileName"
+ "SaveToFile"
],
"lIndex": "2068",
"rIndex": "2221",
@@ -1088,13 +1088,13 @@
"UIView.popupMenu"
],
"deps": [
- "Str2Dir",
+ "CopyFile",
+ "DeleteImageFile",
"FileExists",
"LoadFromFile",
- "CopyFile",
+ "ReSortFileName",
"SaveToFile",
- "DeleteImageFile",
- "ReSortFileName"
+ "Str2Dir"
],
"lIndex": "2222",
"rIndex": "2300",
@@ -1108,8 +1108,8 @@
],
"deps": [
"DeskewImg",
- "SaveToFile",
- "LoadFromFile"
+ "LoadFromFile",
+ "SaveToFile"
],
"lIndex": "2301",
"rIndex": "2323",
@@ -1261,9 +1261,9 @@
"UIView.popupMenu"
],
"deps": [
- "_DelTree",
+ "DeleteDocNoFile",
"DirectoryExists",
- "DeleteDocNoFile"
+ "_DelTree"
],
"lIndex": "2573",
"rIndex": "2677",
@@ -1328,31 +1328,31 @@
"UIView.popupMenu"
],
"deps": [
- "TTiffGraphic",
- "TJpegGraphic",
- "FJpgCompression",
- "DeskewImg",
+ "CheckNeedCrop",
"ConvertToBW",
+ "ConvertToGray",
+ "CropImg",
+ "DeskewImg",
+ "DirectoryExists",
+ "FJpgCompression",
+ "FileExists",
+ "FindFirst",
+ "GetNoNameCase",
+ "LoadFromFile",
"MpsGetBarcode",
"Rotate",
- "CheckNeedCrop",
- "CropImg",
- "ifBlackWhite",
- "tcGroup4",
- "ifColor25",
- "ConvertToGray",
- "tcJpeg",
- "ifTrueColor",
- "ifGray256",
"SaveQuality",
- "FindFirst",
- "LoadFromFile",
"SaveToFile",
- "DirectoryExists",
- "_DelTree",
- "GetNoNameCase",
"Str2Dir",
- "FileExists"
+ "TJpegGraphic",
+ "TTiffGraphic",
+ "_DelTree",
+ "ifBlackWhite",
+ "ifColor25",
+ "ifGray256",
+ "ifTrueColor",
+ "tcGroup4",
+ "tcJpeg"
],
"lIndex": "2789",
"rIndex": "3186",
@@ -1548,11 +1548,11 @@
"UIView.popupMenu"
],
"deps": [
- "_DelTree",
- "SaveToFile",
- "ReSortFileName",
+ "FileExists",
"LoadFromFile",
- "FileExists"
+ "ReSortFileName",
+ "SaveToFile",
+ "_DelTree"
],
"lIndex": "3616",
"rIndex": "3656",
@@ -1684,9 +1684,9 @@
"UIView.toolBar"
],
"deps": [
+ "Scanner",
"SelectScanner",
- "scanner.SelectScanner",
- "Scanner"
+ "scanner.SelectScanner"
],
"lIndex": "4092",
"rIndex": "4100",
@@ -1733,8 +1733,8 @@
"UIView.misc"
],
"deps": [
- "FileExists",
- "CopyFile"
+ "CopyFile",
+ "FileExists"
],
"lIndex": "4165",
"rIndex": "4194",
@@ -1830,8 +1830,8 @@
"UIView.misc"
],
"deps": [
- "SetFtpInfo",
- "IIS_Ftp"
+ "IIS_Ftp",
+ "SetFtpInfo"
],
"lIndex": "4370",
"rIndex": "4378",
@@ -1844,11 +1844,11 @@
"UIView.misc"
],
"deps": [
- "SetFtpInfo",
+ "FJpgCompression",
"IIS_Ftp",
"Rotate",
- "FJpgCompression",
- "Scanner"
+ "Scanner",
+ "SetFtpInfo"
],
"lIndex": "4379",
"rIndex": "4389",
@@ -1861,9 +1861,9 @@
"UIView.misc"
],
"deps": [
- "SaveToFile",
- "FileExists",
"En_DecryptionStr_Base64",
+ "FileExists",
+ "SaveToFile",
"dnFile",
"dnFile_Get"
],
@@ -1878,12 +1878,12 @@
"UIView.misc"
],
"deps": [
- "Str2Dir",
+ "En_DecryptionStr_Base64",
"FileExists",
"LoadFromFile",
"RenameFile",
+ "Str2Dir",
"_DelTree",
- "En_DecryptionStr_Base64",
"upFile"
],
"lIndex": "5014",
@@ -2111,9 +2111,9 @@
"檔案操作"
],
"deps": [
+ "DeleteImageFile",
"FileExists",
"LoadFromFile",
- "DeleteImageFile",
"ReSortFileName",
"SaveToFile"
],
@@ -2130,10 +2130,10 @@
],
"deps": [
"DeleteDocNoFile",
- "SaveToFile",
- "ReSortFileName",
+ "FileExists",
"LoadFromFile",
- "FileExists"
+ "ReSortFileName",
+ "SaveToFile"
],
"lIndex": "6115",
"rIndex": "6140",
@@ -2213,8 +2213,9 @@
"影像處理"
],
"deps": [
- "ImageReSize_FormID",
"FileExists",
+ "ImageReSize_FormID",
+ "ImageResize",
"LoadFromFile"
],
"lIndex": "6320",
@@ -2229,8 +2230,8 @@
"影像處理"
],
"deps": [
- "TDibGraphic",
- "ConvertToBW"
+ "ConvertToBW",
+ "TDibGraphic"
],
"lIndex": "6447",
"rIndex": "6456",
@@ -2243,15 +2244,15 @@
"UIView.misc"
],
"deps": [
- "FileExists",
- "LoadFromFile",
"CopyFile",
+ "FileExists",
"FindFirst",
- "_DelTree",
- "upFile",
- "SetFtpInfo",
+ "FtpCaseComplete",
"IIS_Ftp",
- "FtpCaseComplete"
+ "LoadFromFile",
+ "SetFtpInfo",
+ "_DelTree",
+ "upFile"
],
"lIndex": "6457",
"rIndex": "6734",
@@ -2343,14 +2344,14 @@
"UIView.misc"
],
"deps": [
- "FileExists",
- "Str2Dir",
- "SaveToFile",
- "LoadFromFile",
- "DeleteDocNoFile",
"CopyFile",
+ "DeleteDocNoFile",
"DirectoryExists",
"En_DecryptionStr_Base64",
+ "FileExists",
+ "LoadFromFile",
+ "SaveToFile",
+ "Str2Dir",
"dnFile"
],
"lIndex": "6815",
@@ -2364,8 +2365,8 @@
"UIView.misc"
],
"deps": [
- "SetFtpInfo",
- "IIS_Ftp"
+ "IIS_Ftp",
+ "SetFtpInfo"
],
"lIndex": "6934",
"rIndex": "6979",
@@ -2378,11 +2379,11 @@
"UIView.misc"
],
"deps": [
+ "En_DecryptionStr_Base64",
"FileExists",
"Str2Dir",
- "En_DecryptionStr_Base64",
- "dnFile_Get",
- "dnFile"
+ "dnFile",
+ "dnFile_Get"
],
"lIndex": "6980",
"rIndex": "7032",
@@ -2395,8 +2396,8 @@
"UIView.misc"
],
"deps": [
- "GetNoNameCase",
- "DirectoryExists"
+ "DirectoryExists",
+ "GetNoNameCase"
],
"lIndex": "7033",
"rIndex": "7046",
@@ -2409,11 +2410,11 @@
"UIView.misc"
],
"deps": [
- "LoadFromFile",
"FileExists",
+ "LoadFromFile",
+ "ReSortFileName",
"RenameFile",
- "SaveToFile",
- "ReSortFileName"
+ "SaveToFile"
],
"lIndex": "7047",
"rIndex": "7184",
@@ -2428,9 +2429,9 @@
"deps": [
"FileExists",
"LoadFromFile",
+ "ReSortFileName",
"RenameFile",
- "SaveToFile",
- "ReSortFileName"
+ "SaveToFile"
],
"lIndex": "7185",
"rIndex": "7306",
@@ -2443,8 +2444,8 @@
"UIView.misc"
],
"deps": [
- "LoadFromFile",
- "LoadFileGetMD5"
+ "LoadFileGetMD5",
+ "LoadFromFile"
],
"lIndex": "7307",
"rIndex": "7351",
@@ -2633,10 +2634,10 @@
"UIView.misc"
],
"deps": [
+ "CopyFile",
+ "DirectoryExists",
"FileExists",
"LoadFromFile",
- "DirectoryExists",
- "CopyFile",
"RenameFile",
"SaveToFile"
],
@@ -2729,8 +2730,9 @@
"UIView.misc"
],
"deps": [
- "LoadFromFile",
"FileExists",
+ "GetTag",
+ "LoadFromFile",
"SaveToFile"
],
"lIndex": "8014",
@@ -2949,8 +2951,8 @@
"UIView.misc"
],
"deps": [
- "ifGray256",
"ifBlackWhite",
+ "ifGray256",
"ifTrueColor"
],
"lIndex": "8568",
@@ -3046,9 +3048,9 @@
"UIView.treeView"
],
"deps": [
+ "DirectoryExists",
"FileExists",
- "LoadFromFile",
- "DirectoryExists"
+ "LoadFromFile"
],
"lIndex": "8982",
"rIndex": "9241",
@@ -3089,10 +3091,10 @@
"UIView.misc"
],
"deps": [
+ "CopyFile",
+ "DirectoryExists",
"FileExists",
"LoadFromFile",
- "DirectoryExists",
- "CopyFile",
"SaveToFile"
],
"lIndex": "9376",
@@ -3186,8 +3188,8 @@
],
"deps": [
"FileExists",
- "dnFile_Get",
"dnFile",
+ "dnFile_Get",
"upFile"
],
"lIndex": "9825",
@@ -3215,12 +3217,12 @@
"影像處理"
],
"deps": [
- "FindPoint",
"DirectoryExists",
- "_DelTree",
- "Str2Dir",
+ "FileExists",
+ "FindPoint",
"LoadFromFile",
- "FileExists"
+ "Str2Dir",
+ "_DelTree"
],
"lIndex": "9932",
"rIndex": "9995",
@@ -3707,9 +3709,9 @@
],
"deps": [
"LoadFromFile",
+ "ReSortFileName",
"RenameFile",
- "SaveToFile",
- "ReSortFileName"
+ "SaveToFile"
],
"lIndex": "11390",
"rIndex": "11447",
@@ -3723,9 +3725,9 @@
],
"deps": [
"LoadFromFile",
+ "ReSortFileName",
"RenameFile",
- "SaveToFile",
- "ReSortFileName"
+ "SaveToFile"
],
"lIndex": "11448",
"rIndex": "11505",
@@ -3739,13 +3741,13 @@
"上傳前置資料產生"
],
"deps": [
- "DirectoryExists",
- "_DelTree",
- "Str2Dir",
"CopyFile",
+ "DirectoryExists",
"FileExists",
"LoadFromFile",
- "SaveToFile"
+ "SaveToFile",
+ "Str2Dir",
+ "_DelTree"
],
"lIndex": "11547",
"rIndex": "11672",
@@ -3759,10 +3761,10 @@
"上傳前置資料產生"
],
"deps": [
- "FileExists",
"CopyFile",
- "LoadFromFile",
"DirectoryExists",
+ "FileExists",
+ "LoadFromFile",
"SaveToFile"
],
"lIndex": "11673",
@@ -4017,8 +4019,8 @@
"OMR 檢核"
],
"deps": [
- "LoadFromFile",
- "LoadFileGetMD5"
+ "LoadFileGetMD5",
+ "LoadFromFile"
],
"lIndex": "12209",
"rIndex": "12254",
@@ -4075,10 +4077,10 @@
"影像瀏覽/顯示"
],
"deps": [
+ "DirectoryExists",
"DpiResize",
"FileExists",
- "LoadFromFile",
- "DirectoryExists"
+ "LoadFromFile"
],
"lIndex": "13200",
"rIndex": "13394",
@@ -4103,11 +4105,11 @@
"UIView.toolBar"
],
"deps": [
- "Rotate",
- "TJpegGraphic",
- "SaveQuality",
"LoadFromFile",
- "SaveToFile"
+ "Rotate",
+ "SaveQuality",
+ "SaveToFile",
+ "TJpegGraphic"
],
"lIndex": "13400",
"rIndex": "13422",
@@ -4120,11 +4122,11 @@
"UIView.toolBar"
],
"deps": [
- "Rotate",
- "TJpegGraphic",
- "SaveQuality",
"LoadFromFile",
- "SaveToFile"
+ "Rotate",
+ "SaveQuality",
+ "SaveToFile",
+ "TJpegGraphic"
],
"lIndex": "13423",
"rIndex": "13443",
@@ -4137,11 +4139,11 @@
"UIView.toolBar"
],
"deps": [
- "Rotate",
- "TJpegGraphic",
- "SaveQuality",
"LoadFromFile",
- "SaveToFile"
+ "Rotate",
+ "SaveQuality",
+ "SaveToFile",
+ "TJpegGraphic"
],
"lIndex": "13444",
"rIndex": "13464",
@@ -4573,9 +4575,9 @@
"檔案操作"
],
"deps": [
- "ReSortFileName",
"FileExists",
"LoadFromFile",
+ "ReSortFileName",
"RenameFile",
"SaveToFile"
],
@@ -4591,9 +4593,9 @@
"檔案操作"
],
"deps": [
- "ReSortFileName",
"FileExists",
"LoadFromFile",
+ "ReSortFileName",
"RenameFile",
"SaveToFile"
],
@@ -4609,9 +4611,9 @@
"檔案操作"
],
"deps": [
- "ReSortFileName",
"FileExists",
"LoadFromFile",
+ "ReSortFileName",
"RenameFile",
"SaveToFile"
],
@@ -4630,8 +4632,8 @@
"FileExists",
"LoadFromFile",
"SaveToFile",
- "dnFile_Get",
- "dnFile"
+ "dnFile",
+ "dnFile_Get"
],
"lIndex": "14507",
"rIndex": "14565",
@@ -4648,8 +4650,8 @@
"FileExists",
"LoadFromFile",
"SaveToFile",
- "dnFile_Get",
- "dnFile"
+ "dnFile",
+ "dnFile_Get"
],
"lIndex": "14566",
"rIndex": "14624",
@@ -4677,9 +4679,9 @@
"API 呼叫相關"
],
"deps": [
+ "En_DecryptionStr_Base64",
"FileExists",
- "LoadFromFile",
- "En_DecryptionStr_Base64"
+ "LoadFromFile"
],
"lIndex": "14675",
"rIndex": "14903",
@@ -4694,10 +4696,10 @@
],
"deps": [
"FJpgCompression",
+ "FileExists",
"GetLocalAppDir",
"Str2Dir",
"_DelTree",
- "FileExists",
"initkscan"
],
"lIndex": "14904",
@@ -4750,13 +4752,13 @@
"UIView.treeView"
],
"deps": [
- "RenameFile",
"CopyFile",
"DeleteImageFile",
"LoadFromFile",
+ "ReSortFileName",
+ "RenameFile",
"SaveToFile",
- "_DelTree",
- "ReSortFileName"
+ "_DelTree"
],
"lIndex": "15767",
"rIndex": "15943",
@@ -5527,4 +5529,4 @@
"rIndex": "16455",
"description": "設定倉庫類別(WH_CATEGORY)。此範圍除包含 setter 實作外,亦涵蓋了組件的 initialization 初始區段,負責註冊 ActiveForm 工廠並設定多組授權金鑰(LicenseKey),確保 OCX 運作環境與權限正確初始化。"
}
-]
+]
\ No newline at end of file
diff --git a/iis_image_process.pas b/iis_image_process.pas
new file mode 100644
index 0000000..7c84a7f
--- /dev/null
+++ b/iis_image_process.pas
@@ -0,0 +1,2712 @@
+// 公司 IIS_ImageProcess 相關方法
+unit IIS_ImageProcess;
+
+interface
+uses EnImgScr,
+ EnDiGrph, { for TDibGraphic }
+ EnTifGr, { for TTifGraphic }
+ EnJpgGr, { for TJpegGraphic}
+ EnPngGr, { for TPngGraphic }
+ EnTransf, { for TImageTransform }
+ EnMisc, { for MinFloat }
+ EnRubber, { for TRubberbandMouseHandler }
+ EnPrint, { for TEnvisionPrintMode, TDibGraphicPrinter }
+ DeskewTransform,
+ WatermarkTransform,
+ mpsBarco,
+ NBLib,
+ Barcode,
+ vrsx,
+ dExif,dIPTC,jpeg,
+ windows,Graphics,SysUtils,dialogs,classes,iisunit,Printers,
+ FindBlackSpots,
+ ExtCtrls;
+
+
+Procedure Rotate(Graphic:TDibGraphic;Angle : Double); //旋轉
+Procedure DeskewImg(Graphic : TDibGraphic);Overload; //歪斜矯正
+Procedure DeskewImg(Graphic : TDibGraphic;CR_Graphic : TDibGraphic);Overload; //以黑白影像歪斜矯正後再轉彩色影像
+Procedure CleanupBorder(Graphic : TDibGraphic); // 清黑邊
+procedure NegativeImg(Graphic : TDibGraphic); //反向
+procedure ConvertToGray(Graphic : TDibGraphic); //轉成灰階
+Function GetTag(FileName :String):String; //將資訊從CustomTag裡取出
+Procedure SetTag(FileName,DataStr :String); //將資訊記在CustomTag裡
+Procedure CreateStamp(FileName,Title,UserID,StampDate:String;StampWidth,StampHeight:Single); //產生印章
+procedure CreateNote(FileName,Title:String); //產生便條紙
+procedure CreateDraft(FileName,Title:String); //產生便條紙
+Procedure CreateReportImg(FileName,BarCode,Memo,BGFileName:String;DataList,ItemList:TStringlist); //產生補件清單影像
+Procedure CreateReportImg_JSON(FileName,BGFileName,BarCode,JSONStr:String);
+procedure PrintBarcode(const FileName, Content: WideString; L, T, Width,
+ Height: Integer); //印條碼
+procedure Watermark(logoBmp:TBitmap;Opacity:Byte;Content:String;Graphic:TDibGraphic); //讀bmp印在正中央
+procedure Watermark1(Opacity:Byte;Content,Content1:String;Graphic:TDibGraphic); //自行產生文字330度印在左上右下
+procedure Watermark1_Hong(Opacity:Byte;Content,Content1:String;Graphic:TDibGraphic;ImgH:Integer); //自行產生文字330度印在左上右下
+procedure Watermark1_Hong_New(Opacity:Byte;Content,Content1:String;Graphic,DisGraphic:TDibGraphic;ImgH:Integer); //自行產生文字330度印在左上右下
+
+procedure Watermark2(logoBmp:TBitmap;Opacity:Byte;Content:String;Graphic:TDibGraphic); //讀bmp印在左上方
+Procedure FindPoint(Graphic:TDibGraphic;Var UpPointL,UpPointR,DownPointL:TPoint;Var FormWidth,FormHeight:Integer;Anchor:String);overload;
+Procedure FindPoint(Graphic:TDibGraphic;Var UpPointL,UpPointR,DownPointL:TPoint;Anchor:String);overload;
+function GetBlackSpots(Graphic:TDibGraphic;L, T, R, B, Ratio: Integer): WideString;
+Procedure FindBlackPoint(Graphic:TDibGraphic;Var BlackPoint:Tpoint);
+Function Get_OMR(Graphic:TDibGraphic;iRect:Trect):integer; //取點數
+Function GetSelectRect(ISB:TImageScrollBox):TRect; //取出影像上的框選範圍
+Function GetSelectRect_Back(ISB:TImageScrollBox):TRect; //取出影像上的框選範圍(從右下回來)
+function GetSelectRect2String(ISB:TImageScrollBox;UpPointL:TPoint): WideString; //取出影像上的框選範圍轉公分字串
+function GetSelectRect_Black2String(ISB:TImageScrollBox;BlackPoint:TPoint): WideString; //取出影像上的框選範圍從右下小黑框轉公分字串
+
+Procedure SetSelectRect(ISB:TImageScrollBox;iRect:TRect); //顯示出指定的框
+Procedure SetSelectRect_Original(ISB:TImageScrollBox;iRect:TRect); //顯示出指定的框(不縮放)
+Procedure ShowKeyinRect(ISB:TImageScrollBox;iRect:TRect); //顯示登打位置
+procedure ImageResize(Graphic:TDibGraphic;DesWidth,DesHeight:Integer); //影像縮放
+Procedure DpiResize(Graphic:TDibGraphic;DesDpi:Integer;CheckDpi:Boolean); //改變Dpi並依Dpi縮放影像
+
+Procedure DrawPointLine(ISB:TImageScrollBox;UpPointL,UpPointR,DownPointL:TPoint); //畫十字位置
+Procedure Gray2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer);Overload;
+Procedure Gray2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer;Part:Trect); Overload; //用RTS灰階轉黑白
+Procedure Color2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer); Overload; //用RTS彩色轉黑白
+Procedure Color2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer;Part:Trect); Overload; //用RTS彩色轉黑白
+procedure Emboss(ISB:TImageScrollBox);
+Procedure BrightnessImg(ISB:TImageScrollBox;Precent:Integer); //調整亮度
+Procedure ConvertToBW(Graphic : TDibGraphic); //轉成黑白
+Procedure ConvertTo256Gray(Graphic : TDibGraphic); //轉成256灰階
+
+Procedure ClearLine(Graphic : TDibGraphic;bt:Integer); //清影像上的線條
+procedure CropImg(Graphic : TDibGraphic;iRect:TRect); //切範圍影像
+Function GetPosAngle(UpL,DownL,UpR:TPoint):Single; //取三點夾角角度
+function CheckSize(ISB:TImageScrollBox;UpL,UpR,DownL:TPoint;DefWidth,DefHeight:String): WideString; //檢查Size並縮放
+Function GetPixBW( srcGraphic : TDibGraphic; x,y:integer ):integer;
+Procedure BmpConverJpg(Source,SaveFileName:STring); //Bmp轉不壓縮jpeg
+Procedure BWTif2Jpg(Graphic:TDibGraphic); //黑白Tif轉彩色jpg
+Procedure Color2tif(Graphic:TObject;FileName:String); //彩色影像存Tif
+
+Procedure FieldMask(ISB:TImageScrollBox;SiteList,Mode: WideString;UpPointL:TPoint); //遮罩 Mode:mark mask
+procedure SaveAnnotation(ISB:TImageScrollBox;FileName: WideString); //遮罩存檔
+Procedure FilterColor(SoISB,DeISB:TImageScrollBox;Ration:Integer); //濾掉顏色 留黑白
+procedure JpgReSize_Exif(Maxlength,Quality:integer;OldFile,NewFile:String;WaterGraphic:TGraphic;PrintDate:Boolean); //照片縮放包含Exif
+Function GetExif_CaptureDateTime(FileName : String):String; //取出檔案裡的Exif拍攝日期
+procedure SetKeyinRect_New( ISB:TImageScrollBox; SiteStr, SiteStr_Black,FormHeight: String; UpPointL,UpPointR:TPoint); overload;
+procedure SetKeyinRect_New( ISB:TImageScrollBox; SiteStr, SiteStr_Black,FormHeight: String; UpPointL,UpPointR:TPoint;SP:TShape); overload;
+Procedure Image_Smooth(Graphic:TDibGraphic);
+procedure PrintImg(FileName, LoginID, Datetime,Path: WideString;WaterBmp:TBitmap); overload;
+procedure PrintImg(FileName, LoginID, Datetime,Path: WideString;WaterBmp:TBitmap;Spec_Page:Integer); overload;
+procedure PrintImg(FileName, LoginID, Datetime,Path: WideString;WaterBmp:TBitmap;Spec_Page:Integer;NeedSetup:Boolean); overload;
+
+
+
+implementation
+
+Procedure Rotate(Graphic:TDibGraphic;Angle : Double);
+var
+ Transform : TRotateTransform;
+ AngleStr : String;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(Graphic);
+ Transform := TRotateTransform.Create;
+ try
+ Transform.Angle := Angle;
+ //Transform.BackgroundColor := MakeRgb(255, 255, 255);
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+end;
+
+Procedure DeskewImg(Graphic : TDibGraphic);
+Var
+ Deskew:TDeskewTransform;
+begin
+ // Create a deskew component
+ Deskew:=TDeskewTransform.Create;
+ try
+ //Deskew.ImageExpansion := True;
+ //Deskew.FastEstimation := True;
+ // Apply the deskew transform to the image component
+ Deskew.Apply(Graphic);
+ // Redraw the deskewed image
+ finally
+ //Destroy the deskew component
+ Deskew.Free;
+ end;
+
+end;
+
+Procedure DeskewImg(Graphic : TDibGraphic;CR_Graphic : TDibGraphic);Overload; //以黑白影像歪斜矯正後再轉彩色影像
+Var
+ Deskew:TDeskewTransform;
+ Angle : Single;
+begin
+ // Create a deskew component
+ Deskew:=TDeskewTransform.Create;
+ try
+ //Deskew.ImageExpansion := True;
+ //Deskew.FastEstimation := True;
+ // Apply the deskew transform to the image component
+ Angle := Deskew.DetectSkew(Graphic);
+ Deskew.Apply(Graphic);
+ Rotate(CR_Graphic,Angle);
+ // Redraw the deskewed image
+ finally
+ //Destroy the deskew component
+ Deskew.Free;
+ end;
+
+end;
+
+
+Procedure CleanupBorder(Graphic : TDibGraphic); // 清黑邊
+var
+ Transform : TNBCleanupBorderTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ try
+ FUndoGraphic.Assign(Graphic);
+ Transform := TNBCleanupBorderTransform.Create;
+ try
+ Transform.MarginInches := 5;
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ end;
+ Finally
+ FUndoGraphic.Free;
+ end;
+end;
+
+procedure NegativeImg(Graphic : TDibGraphic); //反向
+var
+ Transform : TNegativeTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ try
+ FUndoGraphic.Assign(Graphic);
+ Transform := TNegativeTransform.Create;
+ try
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ end;
+ finally
+ FUndoGraphic.Free;
+ end;
+end;
+
+procedure ConvertToGray(Graphic : TDibGraphic); //轉灰階
+var
+ Transform : TConvertToGrayTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ try
+ FUndoGraphic.Assign(Graphic);
+ Transform := TConvertToGrayTransform.Create;
+ try
+ //Transform.OnProgress := Self.OnProgress;
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ end;
+ finally
+ FUndoGraphic.Free;
+ end;
+
+end;
+
+Function GetTag(FileName :String):String; //將資訊從CustomTag裡取出
+var
+ Tif : TTiffGraphic;
+begin
+ Result := '';
+ if (Uppercase(ExtractFileExt(FileName)) = '.TIF') or (Uppercase(ExtractFileExt(FileName))='.TIFF') then
+ begin
+ Tif := TTiffGraphic.Create;
+ Try
+ Tif.LoadFromFile(FileName);
+ IF Tif.ImageDescriptionTag <> '' then
+ Result := Tif.ImageDescriptionTag;
+ Finally
+ Tif.Free;
+ end;
+ end;
+end;
+
+Procedure SetTag(FileName,DataStr :String); //將資訊記在CustomTag裡
+var
+ Tif : TTiffGraphic;
+begin
+ if (Uppercase(ExtractFileExt(FileName)) = '.TIF') or (Uppercase(ExtractFileExt(FileName))='.TIFF') then
+ begin
+ Tif := TTiffGraphic.Create;
+ Try
+ Tif.LoadFromFile(FileName);
+ Tif.ImageDescriptionTag := DataStr;
+ Tif.SaveToFile(FileName);
+ Finally
+ Tif.Free;
+ end;
+ end;
+end;
+
+Procedure CreateStamp(FileName,Title,UserID,StampDate:String;StampWidth,StampHeight:Single); //產生印章
+var i,v:integer;
+ bmp:Tbitmap;
+ s:string;
+ ISB : TImageScrollBox;
+ TextH,TextW : Integer;
+ X,Y : Integer;
+ seg:Integer;
+begin
+ IF FileExists(FileName) Then
+ DeleteFile(FileName);
+ //開新影像檔
+ bmp := Tbitmap.Create;
+ ISB := TImageScrollBox.Create(nil);
+ try
+ bmp.Width := Round(StampWidth/2.54 *300);
+ bmp.Height:= Round(StampHeight/ 2.54 *300);
+ bmp.Monochrome := False;
+
+ bmp.Canvas.Font.PixelsPerInch := 300;
+ bmp.Canvas.Font.Size := 24;
+ bmp.Canvas.Font.Style := [fsBold];
+ bmp.Canvas.Font.Name := '標楷體';
+ bmp.Canvas.Font.Color := clBlue;
+
+ bmp.Canvas.Brush.Color:= clwhite;
+ bmp.Canvas.Rectangle(1,1,bmp.Width,bmp.Height);
+
+ bmp.Canvas.Pen.Width:=24;
+ bmp.Canvas.Pen.Color := clblue;
+ bmp.Canvas.Rectangle(1,1,bmp.Width,bmp.Height);
+ bmp.Transparent := True;
+ TextH := bmp.Canvas.TextHeight('退');
+ TextW := bmp.Canvas.TextWidth('退');
+
+ Seg := ((bmp.Height - 60 - TextH) - (Length(Title)*TextH)) Div (length(Title)-1);
+ X := (Bmp.Width Div 2) - (TextW Div 2);
+ Y := 15;
+ for i := 1 to length(Title) do
+ begin
+ bmp.Canvas.TextOut(X,Y,Title[i]);
+ if i < length(Title) then
+ Y := Y + seg +(TextH)
+ else
+ Y := Y + TextH;
+ end;
+ bmp.Canvas.Font.Size := 10;
+ bmp.Canvas.Font.Name := '標楷體';
+ TextW := bmp.Canvas.TextWidth(GetDate);
+ bmp.Canvas.TextOut(((bmp.Width) div 2)-(TextW div 2),Y+20,StampDate);
+ Y := Y + 60;
+ bmp.Canvas.Font.Size := 10;
+ bmp.Canvas.Font.Name := '標楷體';
+ TextW := bmp.Canvas.TextWidth(UserID);
+ bmp.Canvas.TextOut((bmp.Width div 2)-(TextW div 2),Y+20,UserID);
+ {if Title <> '' then
+ begin
+ TextW := bmp.Canvas.TextWidth(Title);
+ bmp.Canvas.TextOut((bmp.Width div 2) - (TextW div 2) ,Round(3*300) ,Title );
+
+ end;}
+ bmp.SaveToFile(ExtractFilePath(FileName)+'tmp.bmp');
+ //ISB.Graphic.Canvas.Assign(bmp.Canvas);
+ ISB.LoadFromFile(ExtractFilePath(FileName)+'tmp.bmp',1);
+ DeleteFile(ExtractFilePath(FileName)+'tmp.bmp');
+ //showmessage(ViewPath+'note.bmp');
+ ISB.Graphic.XDotsPerInch:=300;
+ ISB.Graphic.YDotsPerInch:=300;
+ ISB.SaveToFile(FileName);
+ finally
+ bmp.Free;
+ ISB.Free;
+ end;
+end;
+
+procedure CreateNote(FileName,Title:String); //產生便條紙
+var i,v:integer;
+ bmp:Tbitmap;
+ s:string;
+ ISB : TImageScrollBox;
+ TextW : Integer;
+begin
+ IF FileExists(FileName) Then
+ DeleteFile(FileName);
+ //開新影像檔
+ bmp := Tbitmap.Create;
+ ISB := TImageScrollBox.Create(nil);
+ try
+ bmp.Width := 8 * 300;
+ bmp.Height:= 11 * 300;
+ bmp.Monochrome := true;
+ bmp.Canvas.Font.Size := 60;
+
+ bmp.Canvas.Brush.Color:= clwhite;
+ bmp.Canvas.Rectangle(1,1,bmp.Width,bmp.Height);
+ if Title <> '' then
+ begin
+ TextW := bmp.Canvas.TextWidth(Title);
+ bmp.Canvas.TextOut((bmp.Width div 2) - (TextW div 2) ,Round(3*300) ,Title );
+
+ end;
+ bmp.SaveToFile(ExtractFilePath(FileName)+'tmp.bmp');
+ //ISB.Graphic.Canvas.Assign(bmp.Canvas);
+ ISB.LoadFromFile(ExtractFilePath(FileName)+'tmp.bmp' ,1);
+ DeleteFile(ExtractFilePath(FileName)+'tmp.bmp');
+ //showmessage(ViewPath+'note.bmp');
+ ISB.Graphic.XDotsPerInch:=300;
+ ISB.Graphic.YDotsPerInch:=300;
+ ISB.SaveToFile(FileName);
+ finally
+ bmp.Free;
+ ISB.Free;
+ end;
+end;
+
+procedure CreateDraft(FileName,Title:String); //產生便條紙
+var i,v:integer;
+ bmp:Tbitmap;
+ s:string;
+ ISB : TImageScrollBox;
+ TextW : Integer;
+begin
+ IF FileExists(FileName) Then
+ DeleteFile(FileName);
+ //開新影像檔
+ bmp := Tbitmap.Create;
+ ISB := TImageScrollBox.Create(nil);
+ try
+ bmp.Width := 8 * 300;
+ bmp.Height:= 11 * 300;
+ bmp.Monochrome := False;
+ bmp.Canvas.Font.Size := 60;
+
+ bmp.Canvas.Brush.Color:= clwhite;
+ bmp.Canvas.Rectangle(1,1,bmp.Width,bmp.Height);
+ if Title <> '' then
+ begin
+ TextW := bmp.Canvas.TextWidth(Title);
+ bmp.Canvas.TextOut((bmp.Width div 2) - (TextW div 2) ,Round(0.5*300) ,Title );
+
+ end;
+ bmp.SaveToFile(ExtractFilePath(FileName)+'tmp.bmp');
+ //ISB.Graphic.Canvas.Assign(bmp.Canvas);
+ ISB.LoadFromFile(ExtractFilePath(FileName)+'tmp.bmp' ,1);
+ DeleteFile(ExtractFilePath(FileName)+'tmp.bmp');
+ //showmessage(ViewPath+'note.bmp');
+ ISB.Graphic.XDotsPerInch:=300;
+ ISB.Graphic.YDotsPerInch:=300;
+ ISB.SaveToFile(FileName);
+ finally
+ bmp.Free;
+ ISB.Free;
+ end;
+end;
+
+
+procedure PrintBarcode(const FileName, Content: WideString; L, T,
+ Width, Height: Integer);
+Var
+ Rect : TRect;
+ AsBarCode : TAsBarCode;
+ ISB : TImageScrollBox;
+ TextW : Integer;
+begin
+ AsBarCode := TAsBarCode.Create(nil);
+ ISB := TImageScrollBox.Create(nil);
+ try
+ Rect.Left := L-40;
+ Rect.Top := T-40;
+ Rect.Right := L+Width+40;
+ Rect.Bottom := T+Height+40;
+ ISB.LoadFromFile(FileName,1);
+ ISB.Graphic.Canvas.Brush.Color := clWhite;
+ ISB.Graphic.Canvas.FillRect(Rect);
+ AsBarcode.Typ := bcCode39;
+ AsBarCode.ShowText := bcoNone;
+ AsBarcode.Text := Content;
+ AsBarcode.Left := L;
+ AsBarcode.Top := T;
+ AsBarcode.Width := Width;
+ AsBarcode.Height := Height;
+
+ AsBarCode.DrawBarcode(ISB.Graphic.Canvas);
+
+ ISB.Graphic.Canvas.Font.Size := 28;
+ TextW := ISB.Graphic.Canvas.TextWidth(Content);
+
+ AsBarcode.Left := L + Round(Width Div 2)-(Textw div 2);
+ AsBarcode.Top := T + Height;
+ //AsBarcode.Top := Round(0.1/2.54*ISB.Graphic.XDotsPerInch);
+ AsBarCode.ShowText := bcoCode;
+
+ AsBarCode.DrawText(ISB.Graphic.Canvas);
+ ISB.SaveToFile(FileName);
+ finally
+ AsBarCode.Free;
+ ISB.Free;
+ end;
+end;
+
+Procedure CreateReportImg(FileName,BarCode,Memo,BGFileName:String;DataList,ItemList:TStringlist); //產生補件清單影像
+var i,v,v1:integer;
+ bmp:Tbitmap;
+ s:string;
+ ISB,ISB1 : TImageScrollBox;
+ TextW,TextH,NowX,NowY : Integer;
+ MemoList : TStringlist;
+ DRect,SRect:TRect;
+begin
+ IF FileExists(FileName) Then
+ DeleteFile(FileName);
+ //開新影像檔
+ bmp := Tbitmap.Create;
+ MemoList := TStringlist.Create;
+ ISB := TImageScrollBox.Create(nil);
+ ISB1 := TImageScrollBox.Create(nil);
+ try
+ bmp.Width := 8 * 300;
+ bmp.Height:= 11 * 300;
+ bmp.Monochrome := False;
+ bmp.Canvas.Font.Size := 24;
+ bmp.Canvas.Font.Name := '標楷體';
+
+ bmp.Canvas.Brush.Color:= clwhite;
+ bmp.Canvas.Rectangle(1,1,bmp.Width,bmp.Height);
+
+ TextW := bmp.Canvas.TextWidth('測試');
+ TextH := bmp.Canvas.TextHeight('測試');
+
+ NowY := 600;
+ NowX := bmp.Width Div 2;
+ for i := 0 to DataList.Count - 1 do
+ begin
+
+ NowX := ((bmp.Width Div 2) * (i mod 2)) + 100;
+ bmp.Canvas.TextOut(NowX,NowY,DataList.Strings[i]);
+ NowY := NowY+ ((TextH * (i mod 2))+ (100*(i mod 2)));
+ end;
+ NowY := NowY +TextH+ 100;
+ bmp.Canvas.TextOut(100,NowY,'說明:');
+ NowY := NowY + TextH+20;
+ v:=1;
+ v1:=1;
+ for i := 1 to Length(Memo) do //計算要換行字數
+ begin
+ TextW := bmp.Canvas.TextWidth(Copy(Memo,v,v1));
+
+ if TextW >= (bmp.Width - 250) then
+ begin
+ MemoList.Add(Copy(Memo,v,v1));
+ v := i+1;
+ v1:=0;
+ end;
+ inc(v1);
+ end;
+
+ if v <= length(Memo) then
+ MemoList.Add(Copy(Memo,v,length(Memo)));
+ for i := 0 to MemoList.Count - 1 do
+ begin
+ bmp.Canvas.TextOut(150,NowY,MemoList.Strings[i]);
+ NowY := NowY+TextH+20;
+ end;
+
+ //TextW := bmp.Canvas.TextHeight(Memo);
+
+
+ //bmp.Canvas.TextOut(150,NowY,Memo);
+ NowY := NowY + 100;
+ bmp.Canvas.TextOut(100,NowY,'補件項目:');
+ NowY := NowY +TextH+20;
+
+ for i := 0 to ItemList.Count - 1 do
+ begin
+ bmp.Canvas.TextOut(150,NowY,ItemList.Strings[i]);
+ NowY := NowY+TextH+50;
+ end;
+
+
+ bmp.SaveToFile(ExtractFilePath(FileName)+'tmp.bmp');
+ PrintBarcode(ExtractFilePath(FileName)+'tmp.bmp',BarCode,150,150,1600,150);
+ //ISB.Graphic.Canvas.Assign(bmp.Canvas);
+ ISB.LoadFromFile(ExtractFilePath(FileName)+'tmp.bmp' ,1);
+ DeleteFile(ExtractFilePath(FileName)+'tmp.bmp');
+ ISB1.LoadFromFile(BGFileName,1);
+ Srect := Rect(1,1,ISB.Graphic.Width,ISB.Graphic.Height);
+ DRect := Rect(1,1,ISB1.Graphic.Width,ISB1.Graphic.Height);
+
+ ISB1.Graphic.Canvas.CopyMode := SRCAND;
+ ISB1.Graphic.Canvas.CopyRect(DRect,ISB.Graphic.Canvas,SRect);
+ ISB1.Graphic.XDotsPerInch:=300;
+ ISB1.Graphic.YDotsPerInch:=300;
+ ISB1.SaveToFile(FileName);
+
+ //showmessage(ViewPath+'note.bmp');
+ {ISB.Graphic.XDotsPerInch:=300;
+ ISB.Graphic.YDotsPerInch:=300;
+ ISB.SaveToFile(FileName);}
+ finally
+ bmp.Free;
+ ISB.Free;
+ ISB1.Free;
+ MemoList.Free;
+ end;
+end;
+
+Procedure CreateReportImg_JSON(FileName,BGFileName,BarCode,JSONStr:String);
+var i,n,v,v1:integer;
+ bmp:Tbitmap;
+ s:string;
+ ISB,ISB1 : TImageScrollBox;
+ TextW,TextH,NowX,NowY : Integer;
+ MemoList,ItemList,PrtList : TStringlist;
+ DRect,SRect:TRect;
+begin
+ IF FileExists(FileName) Then
+ DeleteFile(FileName);
+ //開新影像檔
+ bmp := Tbitmap.Create;
+ MemoList := TStringlist.Create;
+ PrtList := TStringlist.Create;
+ ItemList := TStringlist.Create;
+ ISB := TImageScrollBox.Create(nil);
+ ISB1 := TImageScrollBox.Create(nil);
+ try
+ bmp.Width := 8 * 300;
+ bmp.Height:= 11 * 300;
+ bmp.Monochrome := False;
+
+ bmp.Canvas.Font.PixelsPerInch := 300;
+ bmp.Canvas.Font.Size := 12;
+ bmp.Canvas.Font.Name := '標楷體';
+
+ bmp.Canvas.Brush.Color:= clwhite;
+ bmp.Canvas.Rectangle(1,1,bmp.Width,bmp.Height);
+
+ TextW := bmp.Canvas.TextWidth('測試');
+ TextH := bmp.Canvas.TextHeight('測試');
+
+
+ NowY := 600;
+ NowX := bmp.Width Div 2;
+ ////////Title///////
+ PrtList := Getjsonlist(JSONStr,'Title/Content');
+ for i := 0 to PrtList.Count - 1 do
+ begin
+ TextW := bmp.Canvas.TextWidth(PrtList.Strings[i]);
+ NowX := 300;
+ if UpperCase(Getjsondata(JSONStr,'Title/Align')) = 'CENTER' Then
+ NowX := (bmp.Width Div 2) - (TextW Div 2);
+ bmp.Canvas.TextOut(NowX,NowY,PrtList.Strings[i]);
+ NowY := NowY +TextH+ 20;
+ end;
+ ////////Prefix///////
+ NowY := NowY + 80;
+ PrtList := Getjsonlist(JSONStr,'Prefix/Content');
+ for i := 0 to PrtList.Count - 1 do
+ begin
+ TextW := bmp.Canvas.TextWidth(PrtList.Strings[i]);
+ NowX := 300;
+ if UpperCase(Getjsondata(JSONStr,'Prefix/Align')) = 'CENTER' Then
+ NowX := (bmp.Width Div 2) - (TextW Div 2);
+ bmp.Canvas.TextOut(NowX,NowY,PrtList.Strings[i]);
+ NowY := NowY +TextH+ 20;
+ end;
+ ////////Data/////////
+ NowY := NowY + 80;
+ ItemList := GetJsonObjList(JSONStr,'Data/Content');
+ for i := 0 to ItemList.Count - 1 do
+ begin
+ NowX := 300;
+ TextW := bmp.Canvas.TextWidth(ItemList.Strings[i]);
+ if UpperCase(Getjsondata(JSONStr,'Data/Align')) = 'CENTER' Then
+ NowX := (bmp.Width Div 2) - (TextW Div 2);
+ bmp.Canvas.TextOut(NowX,NowY,ItemList.Strings[i]);
+ NowX := NowX +TextW;
+ PrtList := Getjsonlist(JSONStr,'Data/Content/'+ItemList.Strings[i]);
+ for n := 0 to PrtList.Count - 1 do
+ begin
+ TextW := bmp.Canvas.TextWidth(PrtList.Strings[n]);
+ bmp.Canvas.TextOut(NowX,NowY,PrtList.Strings[n]);
+ NowY := NowY +TextH+ 20;
+ end;
+ end;
+ ///////Memo////////
+ NowY := NowY + 80;
+ PrtList := Getjsonlist(JSONStr,'Memo/Content');
+ for i := 0 to PrtList.Count - 1 do
+ begin
+ TextW := bmp.Canvas.TextWidth(PrtList.Strings[i]);
+ NowX := 300;
+ if UpperCase(Getjsondata(JSONStr,'Memo/Align')) = 'CENTER' Then
+ NowX := (bmp.Width Div 2) - (TextW Div 2);
+ bmp.Canvas.TextOut(NowX,NowY,PrtList.Strings[i]);
+ NowY := NowY +TextH+ 20;
+ end;
+ ///////Suffix///////
+ NowY := NowY + 80;
+ PrtList := Getjsonlist(JSONStr,'Suffix/Content');
+ for i := 0 to PrtList.Count - 1 do
+ begin
+ TextW := bmp.Canvas.TextWidth(PrtList.Strings[i]);
+ NowX := 300;
+ if UpperCase(Getjsondata(JSONStr,'Suffix/Align')) = 'CENTER' Then
+ NowX := (bmp.Width Div 2) - (TextW Div 2);
+ bmp.Canvas.TextOut(NowX,NowY,PrtList.Strings[i]);
+ NowY := NowY +TextH+ 20;
+ end;
+ bmp.SaveToFile(ExtractFilePath(FileName)+'tmp.bmp');
+ PrintBarcode(ExtractFilePath(FileName)+'tmp.bmp',BarCode,150,150,1600,150);
+ //ISB.Graphic.Canvas.Assign(bmp.Canvas);
+ ISB.LoadFromFile(ExtractFilePath(FileName)+'tmp.bmp' ,1);
+ DeleteFile(ExtractFilePath(FileName)+'tmp.bmp');
+ ISB1.LoadFromFile(BGFileName,1);
+ Srect := Rect(1,1,ISB.Graphic.Width,ISB.Graphic.Height);
+ DRect := Rect(1,1,ISB1.Graphic.Width,ISB1.Graphic.Height);
+
+ ISB1.Graphic.Canvas.CopyMode := SRCAND;
+ ISB1.Graphic.Canvas.CopyRect(DRect,ISB.Graphic.Canvas,SRect);
+ ISB1.Graphic.XDotsPerInch:=300;
+ ISB1.Graphic.YDotsPerInch:=300;
+ ISB1.SaveToFile(FileName);
+
+ //showmessage(ViewPath+'note.bmp');
+ {ISB.Graphic.XDotsPerInch:=300;
+ ISB.Graphic.YDotsPerInch:=300;
+ ISB.SaveToFile(FileName);}
+ finally
+ bmp.Free;
+ ISB.Free;
+ ISB1.Free;
+ MemoList.Free;
+ PrtList.Free;
+ ItemList.Free;
+ end;
+end;
+
+procedure Watermark(logoBmp:TBitmap;Opacity:Byte;Content:String;Graphic:TDibGraphic);
+Var WatermarkTransform:TWatermarkTransform;
+ WatermarkImage:TDibGraphic;
+ WatermarkImage1:TDibGraphic;
+ S : String;
+ PW,PH : Integer;
+ x,y : Integer;
+ WH,WW : Integer;
+ destrect,sourRect : Trect;
+ WaterH,WaterW : Integer;
+begin
+ // Allows user to select a file (the watermark)
+ // Create the graphics specific for the selected extension
+ WatermarkImage1:=TDibGraphic.Create;
+ WatermarkImage:=TDibGraphic.Create;
+ try
+ // Load the watermark
+ WatermarkImage1.Assign(logoBmp);
+ IF (Graphic.Height > Graphic.Width) Then
+ begin
+ WaterW := (Graphic.Width div 3);
+ WaterH := Round( WatermarkImage1.Height * (WaterW / WatermarkImage1.Width));
+ end
+ Else
+ begin
+ WaterH := (Graphic.Height div 3);
+ WaterW := Round( WatermarkImage1.Width * (WaterH / WatermarkImage1.Height));
+ end;
+
+ WatermarkImage.NewImage(WaterW,WaterH+30,ifTrueColor, nil, 0, 0);
+ WatermarkImage.Canvas.Brush.Color := clWhite;
+ WatermarkImage.Canvas.FillRect(Rect(0,0,WatermarkImage.width,WatermarkImage.Height));
+
+ // Create the watermark transform
+
+
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage1.Width;
+ sourrect.Bottom := WatermarkImage1.Height;
+ destrect.Left := 0;
+ destrect.Top := 0;
+ destrect.Right := WaterW;
+ destrect.Bottom := WaterH;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ WH := Graphic.Height div 2;
+ WW := Graphic.Width div 2;
+
+ WatermarkTransform:=TWatermarkTransform.Create;
+ try
+ // Set the watermark to use
+
+ WatermarkTransform.Watermark:=WatermarkImage;
+ // Select the position where place the watermark: centered !
+
+ WatermarkTransform.Position:=Point(WW -(WatermarkImage.Width div 2),
+ WH -(WatermarkImage.Height div 2));
+
+ //WatermarkTransform.Position:=Point((ImageScrollBox.DisplayedGraphic.Width-WatermarkImage.Width) div 2,
+ // (ImageScrollBox.DisplayedGraphic.Height-WatermarkImage.Height) div 2);
+
+ IF Content <> '' Then
+ begin
+ WatermarkTransform.Watermark.Canvas.Font.Style := [fsBold];
+ WatermarkTransform.Watermark.Canvas.Font.Size := 36;
+ S := Content;
+ PW := WatermarkTransform.Watermark.Canvas.TextWidth(Content);
+ PH := WatermarkTransform.Watermark.Canvas.TextHeight(Content);
+ WatermarkTransform.Watermark.Canvas.TextOut((WatermarkTransform.Watermark.Width - PW) Div 2,WatermarkTransform.Watermark.Height-PH-10,Content);
+ end;
+
+ // Set the opacity %
+ WatermarkTransform.Opacity:=Opacity;
+
+ // Apply the watermark
+ WatermarkTransform.Apply(Graphic);
+ //ImageScrollBox.Redraw(False);
+ //ShowMessage('Watermark applied at image center with 25% opacity !');
+ finally
+ WatermarkTransform.Free;
+ end;
+ finally
+ WatermarkImage.Free;
+ WatermarkImage1.Free;
+ end;
+end;
+
+procedure Watermark1(Opacity:Byte;Content,Content1:String;Graphic:TDibGraphic);
+Var WatermarkTransform:TWatermarkTransform;
+ WatermarkImage:TDibGraphic;
+ WatermarkImage1:TDibGraphic;
+ WatermarkImage2:TDibGraphic;
+ destrect,sourRect : Trect;
+ WaterH,WaterW : Integer;
+ Text_H,Text_W : Integer;
+begin
+ // Allows user to select a file (the watermark)
+ // Create the graphics specific for the selected extension
+ if Content = '' then Exit;
+
+ WatermarkImage1:=TDibGraphic.Create;
+ WatermarkImage2:=TDibGraphic.Create;
+ WatermarkImage:=TDibGraphic.Create;
+ try
+ // Load the watermark
+ //WatermarkImage1.Assign(logoBmp);
+ Graphic.Canvas.Font.Size := 20;
+ Text_W := Graphic.Canvas.TextWidth(Content)+80;
+ Text_H := Graphic.Canvas.TextHeight(Content);
+ WaterW := Text_W;
+ WaterH := Text_W div 6;
+ WatermarkImage1.NewImage(WaterW,WaterH,ifTrueColor, nil, 0, 0);
+ WatermarkImage1.Canvas.Brush.Color := clWhite;
+ WatermarkImage1.Canvas.FillRect(Rect(0,0,WatermarkImage1.width,WatermarkImage1.Height));
+ WatermarkImage1.Canvas.Font.Size := 20;
+ WatermarkImage1.Canvas.Font.Style := [fsBold];
+ WatermarkImage1.Canvas.Font.Name := 'Times New Roman';
+ WatermarkImage1.Canvas.TextOut(1,WaterH div 2,Content);
+ WatermarkImage1.Canvas.TextOut(1,WaterH div 12,content1);
+ Rotate(WatermarkImage1,330); //轉330度
+ WatermarkImage2.NewImage(WaterW,WaterH,ifTrueColor, nil, 0, 0);
+ WatermarkImage2.Canvas.Brush.Color := clWhite;
+ WatermarkImage2.Canvas.FillRect(Rect(0,0,WatermarkImage2.width,WatermarkImage2.Height));
+ WatermarkImage2.Canvas.Font.Size := 20;
+ WatermarkImage2.Canvas.Font.Style := [fsBold];
+ WatermarkImage2.Canvas.Font.Name := 'Times New Roman';
+ WatermarkImage2.Canvas.TextOut(1,WaterH div 2,Content);
+ WatermarkImage2.Canvas.TextOut(1,WaterH div 12,content1);
+ Rotate(WatermarkImage2,225); //轉330度
+ WatermarkImage.NewImage(Graphic.Width,Graphic.Height,ifTrueColor, nil, 0, 0);
+ WatermarkImage.Canvas.Brush.Color := clWhite;
+ WatermarkImage.Canvas.FillRect(Rect(0,0,WatermarkImage.width,WatermarkImage.Height));
+ // Create the watermark transform
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage1.Width;
+ sourrect.Bottom := WatermarkImage1.Height;
+ destrect.Left := 0;
+ destrect.Top := 0;
+ destrect.Right := WatermarkImage1.Width;
+ destrect.Bottom := WatermarkImage1.Height;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage2.Width;
+ sourrect.Bottom := WatermarkImage2.Height;
+ destrect.Left := 0;
+ destrect.Top := WatermarkImage.Height-(WatermarkImage2.Height * 3 div 2);
+ destrect.Right := WatermarkImage2.Width;
+ destrect.Bottom := WatermarkImage.Height-WatermarkImage2.Height div 2;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage2.Canvas,sourrect);
+ {destrect.Left := WatermarkImage.Width-WatermarkImage1.Width;
+ destrect.Top := WatermarkImage.Height-WatermarkImage1.Height;
+ destrect.Right := WatermarkImage.Width;
+ destrect.Bottom := WatermarkImage.Height;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ }
+
+
+
+ WatermarkTransform:=TWatermarkTransform.Create;
+ try
+ // Set the watermark to use
+
+ WatermarkTransform.Watermark:=WatermarkImage;
+ // Select the position where place the watermark: centered !
+
+ WatermarkTransform.Position:=Point(80,80);
+
+ //WatermarkTransform.Position:=Point((ImageScrollBox.DisplayedGraphic.Width-WatermarkImage.Width) div 2,
+ // (ImageScrollBox.DisplayedGraphic.Height-WatermarkImage.Height) div 2);
+
+ // Set the opacity %
+ WatermarkTransform.Opacity:=Opacity;
+
+ // Apply the watermark
+ WatermarkTransform.Apply(Graphic);
+ //ImageScrollBox.Redraw(False);
+ //ShowMessage('Watermark applied at image center with 25% opacity !');
+ finally
+ WatermarkTransform.Free;
+ end;
+ finally
+ WatermarkImage.Free;
+ WatermarkImage1.Free;
+ WatermarkImage2.Free;
+ end;
+end;
+
+procedure Watermark1_Hong(Opacity:Byte;Content,Content1:String;Graphic:TDibGraphic;ImgH:Integer);
+Var WatermarkTransform:TWatermarkTransform;
+ WatermarkImage:TDibGraphic;
+ WatermarkImage1:TDibGraphic;
+ WatermarkImage2:TDibGraphic;
+ destrect,sourRect : Trect;
+ WaterH,WaterW : Integer;
+ Text_H,Text_W : Integer;
+ i,pre : Integer;
+ Zoompercent : Single;
+ Water_SP : Integer;
+ Constr : String;
+begin
+ // Allows user to select a file (the watermark)
+ // Create the graphics specific for the selected extension
+ if Content = '' then Exit;
+ Constr := Content;
+ if length(Content1) > length(Content) then
+ Constr := Content1;
+ //Showmessage(inttostr(ImgH)+#13+inttostr(Graphic.Height)+#13+inttostr(Graphic.XDotsPerInch));
+
+ Zoompercent := Graphic.Height/ImgH *100;
+ //Showmessage(floattostr(Zoompercent));
+ WatermarkImage1:=TDibGraphic.Create;
+ WatermarkImage2:=TDibGraphic.Create;
+ WatermarkImage:=TDibGraphic.Create;
+ try
+ // Load the watermark
+ //WatermarkImage1.Assign(logoBmp);
+ //showmessage(inttostr(Graphic.Width)+#13+inttostr(Graphic.Height));
+ Graphic.Canvas.Font.Style := [fsBold];
+ Graphic.Canvas.Font.Name := '標楷體';
+ Graphic.Canvas.Font.PixelsPerInch := Graphic.XDotsPerInch;
+ Graphic.Canvas.Font.Size := Round(32*(Graphic.XDotsPerInch/300)*Zoompercent/100);
+ {Pre := 16;
+ for i in [36,32,28,26,24,22,20,18,16,14,12,10,8,6] do
+ begin
+ Graphic.Canvas.Font.Size := i;
+ Text_W := Graphic.Canvas.TextWidth(Constr);
+ //Showmessage(inttostr(DGraphic.Canvas.Font.Size)+#13+inttostr(Text_W)+#13+inttostr(DGraphic.Width div 2));
+ if Text_W > ((Graphic.Width div 3) * 2) then
+ begin
+ Graphic.Canvas.Font.Size := Pre;
+ Break;
+ end;
+ Pre := i;
+ end;}
+ //Showmessage(inttostr(Graphic.Canvas.Font.Size));
+ Text_W := Graphic.Canvas.TextWidth(Constr)+Round(1.5/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ //Showmessage(inttostr(Graphic.Canvas.Font.Size)+#13+inttostr(Graphic.Width)+#13+inttostr(Text_W));
+ While Text_W > Graphic.Width do
+ begin
+ Graphic.Canvas.Font.Size := Graphic.Canvas.Font.Size-1;
+ Text_W := Graphic.Canvas.TextWidth(Constr)+Round(1.5/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ //Showmessage(inttostr(Graphic.Canvas.Font.Size)+#13+inttostr(Graphic.Width)+#13+inttostr(Text_W));
+ end;
+ //Showmessage(inttostr(Graphic.Canvas.Font.Size));
+
+ Text_H := Graphic.Canvas.TextHeight(Constr);
+ Water_SP := Round(0.4/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ WaterW := Text_W;
+ WaterH := Text_H*2+Water_SP;// div 6;
+ //Showmessage(inttostr(Text_W)+#13+inttostr(Text_H)+#13+inttostr(WaterH));
+
+ WatermarkImage1.NewImage(WaterW,WaterH,ifTrueColor, nil, Graphic.XDotsPerInch,Graphic.YDotsPerInch);
+ WatermarkImage1.Canvas.Brush.Color := clWhite;
+ WatermarkImage1.Canvas.FillRect(Rect(0,0,WatermarkImage1.width,WatermarkImage1.Height));
+ WatermarkImage1.Canvas.Font.PixelsPerInch := Graphic.XDotsPerInch;
+ WatermarkImage1.Canvas.Font.Size := Graphic.Canvas.Font.Size;
+ WatermarkImage1.Canvas.Font.Style := [fsBold];
+ WatermarkImage1.Canvas.Font.Name := '標楷體';
+ WatermarkImage1.Canvas.TextOut(1,1,Content);
+ WatermarkImage1.Canvas.TextOut(1,Text_H div 2+Water_SP,content1);
+ //Showmessage(inttostr(WatermarkImage1.Width)+#13+inttostr(WatermarkImage1.Height));
+ Rotate(WatermarkImage1,-30); //轉330度
+ //Showmessage(inttostr(WatermarkImage1.Width)+#13+inttostr(WatermarkImage1.Height));
+ WatermarkImage2.NewImage(WaterW,WaterH,ifTrueColor, nil, 0, 0);
+ WatermarkImage2.Canvas.Brush.Color := clWhite;
+ WatermarkImage2.Canvas.FillRect(Rect(0,0,WatermarkImage2.width,WatermarkImage2.Height));
+ WatermarkImage2.Canvas.Font.PixelsPerInch := Graphic.XDotsPerInch;
+ WatermarkImage2.Canvas.Font.Size := Graphic.Canvas.Font.Size;
+ WatermarkImage2.Canvas.Font.Style := [fsBold];
+ WatermarkImage2.Canvas.Font.Name := '標楷體';
+ WatermarkImage2.Canvas.TextOut(1,1,Content);
+ WatermarkImage2.Canvas.TextOut(1,Text_H div 2+Water_SP,content1);
+ //WatermarkImage2.Canvas.TextOut(1,WaterH div 2,Content);
+ //WatermarkImage2.Canvas.TextOut(1,WaterH div 12,content1);
+ Rotate(WatermarkImage2,40); //轉330度
+ WatermarkImage.NewImage(Graphic.Width,Graphic.Height,ifTrueColor, nil, 0, 0);
+ WatermarkImage.Canvas.Brush.Color := clWhite;
+ WatermarkImage.Canvas.FillRect(Rect(0,0,WatermarkImage.width,WatermarkImage.Height));
+
+ // Create the watermark transform
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage1.Width;
+ sourrect.Bottom := WatermarkImage1.Height;
+ //showmessage(inttostr(Zoompercent)+#13+inttostr(Round(1/2.54*Graphic.XDotsPerInch*Zoompercent/100)));
+ destrect.Left := Round(3/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ destrect.Top := (WatermarkImage.Height Div 4)-(WatermarkImage1.Height div 2);
+ destrect.Right := destrect.Left+WatermarkImage1.Width;
+ destrect.Bottom := destrect.Top + WatermarkImage1.Height;
+ //Showmessage(inttostr(WatermarkImage.Height)+#13+inttostr(destrect.Top)+#13+inttostr(destrect.Bottom)+#13+inttostr(WatermarkImage1.Height));
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage2.Width;
+ sourrect.Bottom := WatermarkImage2.Height;
+ destrect.Left := Round(3/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ destrect.Top := ((WatermarkImage.Height div 4) * 3) -(WatermarkImage2.Height div 2);
+ destrect.Right := destrect.Left+WatermarkImage2.Width;
+ destrect.Bottom := destrect.Top+WatermarkImage2.Height;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage2.Canvas,sourrect);
+ {destrect.Left := WatermarkImage.Width-WatermarkImage1.Width;
+ destrect.Top := WatermarkImage.Height-WatermarkImage1.Height;
+ destrect.Right := WatermarkImage.Width;
+ destrect.Bottom := WatermarkImage.Height;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ }
+
+
+
+ WatermarkTransform:=TWatermarkTransform.Create;
+ try
+ // Set the watermark to use
+
+ WatermarkTransform.Watermark:=WatermarkImage;
+ // Select the position where place the watermark: centered !
+
+ WatermarkTransform.Position:=Point(0,0);
+
+ //WatermarkTransform.Position:=Point((ImageScrollBox.DisplayedDGraphic.Width-WatermarkImage.Width) div 2,
+ // (ImageScrollBox.DisplayedDGraphic.Height-WatermarkImage.Height) div 2);
+
+ // Set the opacity %
+ WatermarkTransform.Opacity:=Opacity;
+
+ // Apply the watermark
+ WatermarkTransform.Apply(Graphic);
+ //ImageScrollBox.Redraw(False);
+ //ShowMessage('Watermark applied at image center with 25% opacity !');
+ finally
+ WatermarkTransform.Free;
+ end;
+ finally
+ WatermarkImage.Free;
+ WatermarkImage1.Free;
+ WatermarkImage2.Free;
+ end;
+end;
+
+procedure Watermark1_Hong_New(Opacity:Byte;Content,Content1:String;Graphic,DisGraphic:TDibGraphic;ImgH:Integer); //自行產生文字330度印在左上右下
+Var WatermarkTransform:TWatermarkTransform;
+ WatermarkImage:TDibGraphic;
+ WatermarkImage1:TDibGraphic;
+ WatermarkImage2:TDibGraphic;
+ destrect,sourRect : Trect;
+ WaterH,WaterW : Integer;
+ Text_H,Text_W : Integer;
+ i,pre : Integer;
+ Zoompercent : Single;
+ Water_SP : Integer;
+ Constr : String;
+begin
+ // Allows user to select a file (the watermark)
+ // Create the graphics specific for the selected extension
+ if Content = '' then Exit;
+ Constr := Content;
+ if length(Content1) > length(Content) then
+ Constr := Content1;
+ //Showmessage(inttostr(ImgH)+#13+inttostr(Graphic.Height)+#13+inttostr(Graphic.XDotsPerInch));
+
+ Zoompercent := DisGraphic.Height/ImgH *100;
+ //Showmessage(floattostr(Zoompercent));
+ WatermarkImage1:=TDibGraphic.Create;
+ WatermarkImage2:=TDibGraphic.Create;
+ WatermarkImage:=TDibGraphic.Create;
+ try
+ // Load the watermark
+ //WatermarkImage1.Assign(logoBmp);
+ //showmessage(inttostr(Graphic.Width)+#13+inttostr(Graphic.Height));
+ Graphic.Canvas.Font.Style := [fsBold];
+ Graphic.Canvas.Font.Name := '標楷體';
+ Graphic.Canvas.Font.PixelsPerInch := Graphic.XDotsPerInch;
+ Graphic.Canvas.Font.Size := 16;
+
+ {Pre := 16;
+ for i in [36,32,28,26,24,22,20,18,16,14,12,10,8,6] do
+ begin
+ Graphic.Canvas.Font.Size := i;
+ Text_W := Graphic.Canvas.TextWidth(Constr);
+ //Showmessage(inttostr(DGraphic.Canvas.Font.Size)+#13+inttostr(Text_W)+#13+inttostr(DGraphic.Width div 2));
+ if Text_W > ((Graphic.Width div 3) * 2) then
+ begin
+ Graphic.Canvas.Font.Size := Pre;
+ Break;
+ end;
+ Pre := i;
+ end;}
+ //Showmessage(inttostr(DGraphic.Canvas.Font.Size));
+ Text_W := Graphic.Canvas.TextWidth(Constr)+Round(1.5/2.54*Graphic.XDotsPerInch);
+ //Showmessage(inttostr(Graphic.Canvas.Font.Size)+#13+inttostr(Graphic.Width)+#13+inttostr(Text_W));
+
+
+ Text_H := Graphic.Canvas.TextHeight(Constr);
+ Water_SP := Round(0.4/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ WaterW := Text_W;
+ WaterH := Text_H*2+Water_SP;// div 6;
+ //Showmessage(inttostr(Text_W)+#13+inttostr(Text_H)+#13+inttostr(WaterH));
+
+ WatermarkImage1.NewImage(WaterW,WaterH,ifTrueColor, nil, Graphic.XDotsPerInch,Graphic.YDotsPerInch);
+ WatermarkImage1.Canvas.Brush.Color := clWhite;
+ WatermarkImage1.Canvas.FillRect(Rect(0,0,WatermarkImage1.width,WatermarkImage1.Height));
+ WatermarkImage1.Canvas.Font.PixelsPerInch := Graphic.XDotsPerInch;
+ WatermarkImage1.Canvas.Font.Size := Graphic.Canvas.Font.Size;
+ WatermarkImage1.Canvas.Font.Style := [fsBold];
+ WatermarkImage1.Canvas.Font.Name := '標楷體';
+ WatermarkImage1.Canvas.TextOut(1,1,Content);
+ WatermarkImage1.Canvas.TextOut(1,Text_H div 2+Water_SP,content1);
+ //Showmessage(inttostr(WatermarkImage1.Width)+#13+inttostr(WatermarkImage1.Height));
+ Rotate(WatermarkImage1,-30); //轉330度
+ //Showmessage(inttostr(WatermarkImage1.Width)+#13+inttostr(WatermarkImage1.Height));
+ WatermarkImage2.NewImage(WaterW,WaterH,ifTrueColor, nil, 0, 0);
+ WatermarkImage2.Canvas.Brush.Color := clWhite;
+ WatermarkImage2.Canvas.FillRect(Rect(0,0,WatermarkImage2.width,WatermarkImage2.Height));
+ WatermarkImage2.Canvas.Font.PixelsPerInch := Graphic.XDotsPerInch;
+ WatermarkImage2.Canvas.Font.Size := Graphic.Canvas.Font.Size;
+ WatermarkImage2.Canvas.Font.Style := [fsBold];
+ WatermarkImage2.Canvas.Font.Name := '標楷體';
+ WatermarkImage2.Canvas.TextOut(1,1,Content);
+ WatermarkImage2.Canvas.TextOut(1,Text_H div 2+Water_SP,content1);
+ //WatermarkImage2.Canvas.TextOut(1,WaterH div 2,Content);
+ //WatermarkImage2.Canvas.TextOut(1,WaterH div 12,content1);
+ Rotate(WatermarkImage2,-150); //轉330度
+ WatermarkImage.NewImage(DisGraphic.Width,DisGraphic.Height,ifTrueColor, nil, 0, 0);
+ WatermarkImage.Canvas.Brush.Color := clWhite;
+ WatermarkImage.Canvas.FillRect(Rect(0,0,WatermarkImage.width,WatermarkImage.Height));
+
+ // Create the watermark transform
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage1.Width;
+ sourrect.Bottom := WatermarkImage1.Height;
+ //showmessage(inttostr(Zoompercent)+#13+inttostr(Round(1/2.54*Graphic.XDotsPerInch*Zoompercent/100)));
+ destrect.Left := Round(1/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ destrect.Top := (WatermarkImage.Height Div 4)-(Round(WatermarkImage1.Height*Zoompercent/100) div 2);
+ destrect.Right := destrect.Left+Round(WatermarkImage1.Width*Zoompercent/100);
+ destrect.Bottom := destrect.Top + Round(WatermarkImage1.Height*Zoompercent/100);
+ //Showmessage(inttostr(WatermarkImage.Height)+#13+inttostr(destrect.Top)+#13+inttostr(destrect.Bottom)+#13+inttostr(WatermarkImage1.Height));
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage2.Width;
+ sourrect.Bottom := WatermarkImage2.Height;
+ destrect.Left := Round(1/2.54*Graphic.XDotsPerInch*Zoompercent/100);
+ destrect.Top := ((WatermarkImage.Height div 4) * 3) -(Round(WatermarkImage2.Height*Zoompercent/100) div 2);
+ destrect.Right := destrect.Left+Round(WatermarkImage2.Width*Zoompercent/100);
+ destrect.Bottom := destrect.Top+Round(WatermarkImage2.Height*Zoompercent/100);
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage2.Canvas,sourrect);
+ {destrect.Left := WatermarkImage.Width-WatermarkImage1.Width;
+ destrect.Top := WatermarkImage.Height-WatermarkImage1.Height;
+ destrect.Right := WatermarkImage.Width;
+ destrect.Bottom := WatermarkImage.Height;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ }
+
+
+
+ WatermarkTransform:=TWatermarkTransform.Create;
+ try
+ // Set the watermark to use
+
+ WatermarkTransform.Watermark:=WatermarkImage;
+ // Select the position where place the watermark: centered !
+
+ WatermarkTransform.Position:=Point(0,0);
+
+ //WatermarkTransform.Position:=Point((ImageScrollBox.DisplayedDGraphic.Width-WatermarkImage.Width) div 2,
+ // (ImageScrollBox.DisplayedDGraphic.Height-WatermarkImage.Height) div 2);
+
+ // Set the opacity %
+ WatermarkTransform.Opacity:=Opacity;
+
+ // Apply the watermark
+ WatermarkTransform.Apply(DisGraphic);
+ //ImageScrollBox.Redraw(False);
+ //ShowMessage('Watermark applied at image center with 25% opacity !');
+ finally
+ WatermarkTransform.Free;
+ end;
+ finally
+ WatermarkImage.Free;
+ WatermarkImage1.Free;
+ WatermarkImage2.Free;
+ end;
+end;
+
+procedure Watermark2(logoBmp:TBitmap;Opacity:Byte;Content:String;Graphic:TDibGraphic);
+Var WatermarkTransform:TWatermarkTransform;
+ WatermarkImage:TDibGraphic;
+ WatermarkImage1:TDibGraphic;
+ S : String;
+ PW,PH : Integer;
+ x,y : Integer;
+ WH,WW : Integer;
+ destrect,sourRect : Trect;
+ WaterH,WaterW : Integer;
+begin
+ // Allows user to select a file (the watermark)
+ // Create the graphics specific for the selected extension
+ WatermarkImage1:=TDibGraphic.Create;
+ WatermarkImage:=TDibGraphic.Create;
+ try
+ // Load the watermark
+ WatermarkImage1.Assign(logoBmp);
+ IF (Graphic.Height > Graphic.Width) Then
+ begin
+ WaterW := Round((1.2 / 2.54) * Graphic.XDotsPerInch);
+ WaterH := Round((5 / 2.54) * Graphic.XDotsPerInch);
+ //WaterW := (Graphic.Width div 18);
+ //WaterH := Round( WatermarkImage1.Height * (WaterW / WatermarkImage1.Width));
+ end
+ Else
+ begin
+ WaterW := Round((1.2 / 2.54) * Graphic.XDotsPerInch);
+ WaterH := Round((5 / 2.54) * Graphic.XDotsPerInch);
+ //WaterH := (Graphic.Height div 18);
+ //WaterW := Round( WatermarkImage1.Width * (WaterH / WatermarkImage1.Height));
+ end;
+
+ WatermarkImage.NewImage(WaterW,WaterH+30,ifTrueColor, nil, 0, 0);
+ WatermarkImage.Canvas.Brush.Color := clWhite;
+ WatermarkImage.Canvas.FillRect(Rect(0,0,WatermarkImage.width,WatermarkImage.Height));
+
+ // Create the watermark transform
+
+
+ sourrect.Left := 0;
+ sourrect.Top := 0;
+ sourrect.Right := WatermarkImage1.Width;
+ sourrect.Bottom := WatermarkImage1.Height;
+ destrect.Left := 0;
+ destrect.Top := 0;
+ destrect.Right := WaterW;
+ destrect.Bottom := WaterH;
+ WatermarkImage.Canvas.CopyRect(destrect,WatermarkImage1.Canvas,sourrect);
+ WH := Graphic.Height div 2;
+ WW := Graphic.Width div 2;
+
+ WatermarkTransform:=TWatermarkTransform.Create;
+ try
+ // Set the watermark to use
+
+ WatermarkTransform.Watermark:=WatermarkImage;
+ // Select the position where place the watermark: centered !
+
+ {WatermarkTransform.Position:=Point(WW -(WatermarkImage.Width div 2),
+ WH -(WatermarkImage.Height div 2));}
+ WatermarkTransform.Position:=Point(20,20);
+
+ //WatermarkTransform.Position:=Point((ImageScrollBox.DisplayedGraphic.Width-WatermarkImage.Width) div 2,
+ // (ImageScrollBox.DisplayedGraphic.Height-WatermarkImage.Height) div 2);
+
+ IF Content <> '' Then
+ begin
+ WatermarkTransform.Watermark.Canvas.Font.Style := [fsBold];
+ WatermarkTransform.Watermark.Canvas.Font.Size := 36;
+ S := Content;
+ PW := WatermarkTransform.Watermark.Canvas.TextWidth(Content);
+ PH := WatermarkTransform.Watermark.Canvas.TextHeight(Content);
+ WatermarkTransform.Watermark.Canvas.TextOut((WatermarkTransform.Watermark.Width - PW) Div 2,WatermarkTransform.Watermark.Height-PH-10,Content);
+ end;
+
+ // Set the opacity %
+ WatermarkTransform.Opacity:=Opacity;
+
+ // Apply the watermark
+ WatermarkTransform.Apply(Graphic);
+ //ImageScrollBox.Redraw(False);
+ //ShowMessage('Watermark applied at image center with 25% opacity !');
+ finally
+ WatermarkTransform.Free;
+ end;
+ finally
+ WatermarkImage.Free;
+ WatermarkImage1.Free;
+ end;
+end;
+
+Procedure FindPoint(Graphic:TDibGraphic;Var UpPointL,UpPointR,DownPointL:TPoint;Var FormWidth,FormHeight:Integer;Anchor:String);
+var
+ XDpi,YDpi : Integer;
+ XLen,XLen1,YLen : Integer;
+ LSeg,RSeg : Integer;
+ compsize : Integer;
+begin
+ XDpi := Graphic.XDotsPerInch;
+ YDpi := Graphic.YDotsPerInch;
+ XLen := Round(1 * XDpi);
+ XLen1 := Round(4 * XDpi);
+ YLen := Round(1 * XDpi);
+ LSeg := 1;//Round(0.1 / 2.54 * XDpi);
+ RSeg := 1;
+ compsize := Round(0.15/2.54 * XDpi); //要找定位的長度
+ if Anchor <> 'NONE' then
+ begin
+
+ UpPointL := Checked_Start(Graphic,LSeg,LSeg,XLen,YLen ,compsize,1,Anchor);
+ IF ((UpPointL.X=0) and (UpPointL.Y=0)) Then
+ UpPointL := Checked_Start(Graphic,LSeg,LSeg,XLen1,YLen ,compsize,1,Anchor);
+
+ DownPointL := Checked_Start(Graphic,Lseg,Graphic.Height- Lseg,XLen,Graphic.Height-YLen ,compsize,2,Anchor); //ToY必須>=compsize
+ IF ((DownPointL.X=0) and (DownPointL.Y=Graphic.Height)) Then
+ begin
+ DownPointL := Checked_Start(Graphic,Lseg,Graphic.Height- Lseg,XLen1,Graphic.Height-YLen ,compsize,2,Anchor);
+ end;
+ UpPointR := Checked_Start(Graphic,Graphic.Width - Rseg,Rseg,Graphic.Width-XLen,YLen ,compsize,3,Anchor); //FromX必須>=compsize
+ FormWidth := UpPointR.X - UpPointL.X;
+ FormHeight := DownPointL.Y - UpPointL.Y;
+ end
+ Else
+ begin
+ UpPointL.X := 0;
+ UpPointL.Y := 0;
+ FormWidth := Graphic.Width;
+ FormHeight := Graphic.Height;
+ end;
+
+ {IF ((UpPointR.X=ImageScrollBox1.Graphic.Width)and(UpPointR.Y=0)) Then
+ UpPointR := Checked_Start(ISB_BW.Graphic,ImageScrollBox1.Graphic.Width - Rseg,Rseg,ImageScrollBox1.Graphic.Width-XLen1,YLen ,compsize,3,AnchorMode); //FromX必須>=compsize
+ }
+ //DownPointR := Checked_Start(ISB_BW.Graphic,ImageScrollBox1.Graphic.Width -Rseg,ImageScrollBox1.Graphic.Height- Rseg,ImageScrollBox1.Graphic.Width-XLen ,ImageScrollBox1.Graphic.Height-YLen ,compsize,4,AnchorMode); //FromX必須>=compsize
+
+end;
+
+Procedure FindPoint(Graphic:TDibGraphic;Var UpPointL,UpPointR,DownPointL:TPoint;Anchor:String);overload;
+var
+ XDpi,YDpi : Integer;
+ XLen,XLen1,YLen : Integer;
+ LSeg,RSeg : Integer;
+ compsize : Integer;
+begin
+ XDpi := Graphic.XDotsPerInch;
+ YDpi := Graphic.YDotsPerInch;
+ XLen := Round(1 * XDpi);
+ XLen1 := Round(4 * XDpi);
+ YLen := Round(1 * XDpi);
+ LSeg := 1;//Round(0.1 / 2.54 * XDpi);
+ RSeg := 1;
+ compsize := Round(0.15/2.54 * XDpi); //要找定位的長度
+ UpPointL := Checked_Start(Graphic,LSeg,LSeg,XLen,YLen ,compsize,1,Anchor);
+ IF ((UpPointL.X=0) and (UpPointL.Y=0)) Then
+ UpPointL := Checked_Start(Graphic,LSeg,LSeg,XLen1,YLen ,compsize,1,Anchor);
+
+ DownPointL := Checked_Start(Graphic,Lseg,Graphic.Height- Lseg,XLen,Graphic.Height-YLen ,compsize,2,Anchor); //ToY必須>=compsize
+ IF ((DownPointL.X=0) and (DownPointL.Y=Graphic.Height)) Then
+ begin
+ DownPointL := Checked_Start(Graphic,Lseg,Graphic.Height- Lseg,XLen1,Graphic.Height-YLen ,compsize,2,Anchor);
+ end;
+ UpPointR := Checked_Start(Graphic,Graphic.Width - Rseg,Rseg,Graphic.Width-XLen,YLen ,compsize,3,Anchor); //FromX必須>=compsize
+end;
+
+function GetBlackSpots(Graphic:TDibGraphic;L, T, R, B, Ratio: Integer): WideString;
+var
+ S : TStringlist;
+ i : Integer;
+begin
+ Result := '';
+ IF Graphic.ImageFormat = ifBlackWhite Then
+ begin
+ S := TStringlist.Create;
+ try
+ DorwFindRect(Graphic,L,T,R,B,Ratio);
+ for i := 1 to BlackSpotsCount do
+ begin
+ S.Add(Format('%d,%d,%d,%d',[BlackSpots[i].Left,BlackSpots[i].Top,BlackSpots[i].Right,BlackSpots[i].Bottom ]));
+ end;
+ Result := S.Text;
+ Finally
+ S.Free;
+ end;
+ end;
+end;
+
+Procedure FindBlackPoint(Graphic:TDibGraphic;Var BlackPoint:Tpoint);
+var
+ Seg : Integer;
+ W,H : Integer;
+ BlackSpotList,SiteList : TStringlist;
+ i : Integer;
+ P : TPoint;
+begin
+ BlackPoint.X := 0;
+ BlackPoint.Y := 0;
+
+ IF Graphic.ImageFormat = ifBlackWhite Then
+ begin
+ BlackSpotList := TStringlist.Create;
+ SiteList := TStringlist.Create;
+ try
+
+ Seg := Round(1/2.54*Graphic.XDotsPerInch); //1公分的邊
+ W := Graphic.Width;
+ H := Graphic.Height;
+ BlackSpotList.Text := GetBlackSpots(Graphic,W-Seg,0,W,H,80);
+
+ If BlackSpotList.Count > 0 Then
+ begin
+ BlackPoint := Str2Point(BlackSpotList.Strings[0]);
+ end;
+
+ For i:=1 to BlackSpotList.Count -1 do
+ begin
+ P := Str2Point(BlackSpotList.Strings[i]);
+ If (p.X+p.Y) > (BlackPoint.X +BlackPoint.Y) Then
+ begin
+ BlackPoint := p;
+ end;
+ end;
+ finally
+ BlackSpotList.Free;
+ SiteList.Free;
+ end;
+ end;
+
+end;
+
+Function Get_OMR(Graphic:TDibGraphic;iRect:Trect):integer; //取點數
+var i,n,x,y:integer;
+begin
+ i:=0;
+ n:=0;
+ for y := iRect.Top to iRect.Bottom -1 do
+ for x := iRect.Left to iRect.Right -1 do
+ begin
+ if Graphic.Canvas.Pixels[x,y] = clBlack Then
+ inc(n);
+ end;
+ result :=n;
+end;
+
+
+
+Function GetSelectRect(ISB:TImageScrollBox):TRect; //取出影像上的框選範圍
+var
+ Rt: TRect;
+ XDpi,YDpi : single;
+ ct : Integer;
+begin
+ Result := Rect(0,0,0,0);
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ if ISB.MouseHandler is TRubberBandMouseHandler then
+ begin
+ TRubberBandMouseHandler(ISB.MouseHandler).GetSourceSelection(Rt);
+ Result := Rt;
+ end;
+end;
+
+function GetSelectRect2String(ISB:TImageScrollBox;UpPointL:TPoint): WideString;
+var
+ rt2: trect;
+ XDpi,YDpi : single;
+ ct : Integer;
+ L,T,R,B : String;
+begin
+ //IF (X1 = X2) and (Y1 = Y2) Then Exit;
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ if ISB.MouseHandler is TRubberBandMouseHandler then
+ begin
+ TRubberBandMouseHandler(ISB.MouseHandler).GetSourceSelection(rt2);
+ L := Format('%3.2f',[(rt2.Left - UpPointL.X) / Xdpi * 2.54 ]);
+ T := Format('%3.2f',[(rt2.Top - UpPointL.Y) / Xdpi * 2.54]);
+ R := Format('%3.2f',[(rt2.right - UpPointL.X) / Xdpi * 2.54]);
+ B := Format('%3.2f',[(rt2.bottom - UpPointL.Y)/ Xdpi * 2.54]);
+ Result := L+#13+T+#13+R+#13+B;
+ end;
+end;
+
+Procedure SetSelectRect(ISB:TImageScrollBox;iRect:TRect); //顯示出指定的框
+var
+ Rt : TRect;
+ XDpi,YDpi : single;
+ XZoom : Single;
+ YZoom : Single;
+begin
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ rt.Left :=Round(iRect.Left*ISB.ZoomPercent/100);
+ rt.Top :=Round(iRect.Top*ISB.ZoomPercent/100);
+ rt.Right :=Round(iRect.Right*ISB.ZoomPercent/100);
+ rt.Bottom :=Round(iRect.Bottom*ISB.ZoomPercent/100);
+ //20200217 加這段讓運算後可能不到1的變1,才能順利畫出框
+ if rt.Left = 0 then Rt.Left := 1;
+ if rt.Top = 0 then Rt.Top := 1;
+ if rt.Right = isb.DisplayedGraphic.Width then
+ rt.Right := isb.DisplayedGraphic.Width-1;
+ if rt.Bottom = isb.DisplayedGraphic.Height then
+ rt.Bottom := isb.DisplayedGraphic.Height-1;
+ //20200217 加這段讓運算後可能不到1的變1,才能順利畫出框
+
+
+ if ISB.MouseHandler is TRubberBandMouseHandler then
+ begin
+ TRubberBandMouseHandler(ISB.MouseHandler).setselectrect(rt);
+ end;
+ ISB.HorzScrollBar.Position := rt.Left;
+ ISB.VertScrollBar.Position := rt.Top-20;
+end;
+
+Procedure SetSelectRect_Original(ISB:TImageScrollBox;iRect:TRect); //顯示出指定的框(不縮放)
+var
+ Rt : TRect;
+ XDpi,YDpi : single;
+ XZoom : Single;
+ YZoom : Single;
+begin
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ rt.Left :=Round(iRect.Left);
+ rt.Top :=Round(iRect.Top);
+ rt.Right :=Round(iRect.Right);
+ rt.Bottom :=Round(iRect.Bottom);
+ if ISB.MouseHandler is TRubberBandMouseHandler then
+ begin
+ TRubberBandMouseHandler(ISB.MouseHandler).setselectrect(rt);
+ end;
+ ISB.HorzScrollBar.Position := rt.Left;
+ ISB.VertScrollBar.Position := rt.Top-20;
+end;
+
+Function GetSelectRect_Back(ISB:TImageScrollBox):TRect; //取出影像上的框選範圍(從右下回來)
+var
+ rt2: trect;
+ ct : Integer;
+ L1,T1,R1,B1 : String;
+begin
+ //IF (X1 = X2) and (Y1 = Y2) Then Exit;
+ Result := Rect(0,0,0,0);
+ if ISB.MouseHandler is TRubberBandMouseHandler then
+ begin
+ TRubberBandMouseHandler(ISB.MouseHandler).GetSourceSelection(rt2);
+ rt2.Left := ISB.Graphic.Width - rt2.Left;
+ rt2.Top := ISB.Graphic.Height - rt2.Top;
+ rt2.Right := ISB.Graphic.Width - rt2.Right;
+ rt2.Bottom := ISB.Graphic.Height - rt2.Bottom;
+ Result := rt2;
+ end;
+end;
+
+function GetSelectRect_Black2String(ISB:TImageScrollBox;BlackPoint:TPoint): WideString;
+var
+ rt2: trect;
+ XDpi,YDpi : single;
+ ct : Integer;
+ L1,T1,R1,B1 : String;
+begin
+ //IF (X1 = X2) and (Y1 = Y2) Then Exit;
+ Result := '';
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ if ISB.MouseHandler is TRubberBandMouseHandler then
+ begin
+ TRubberBandMouseHandler(ISB.MouseHandler).GetSourceSelection(rt2);
+ IF (BlackPoint.X > 0) and (BlackPoint.Y > 0) Then
+ begin
+ L1 := Format('%3.2f',[(BlackPoint.X - rt2.Left) / Xdpi * 2.54 ]);
+ T1 := Format('%3.2f',[(BlackPoint.Y - rt2.Top) / Xdpi * 2.54]);
+ R1 := Format('%3.2f',[(BlackPoint.X - rt2.right) / Xdpi * 2.54]);
+ B1 := Format('%3.2f',[(BlackPoint.Y - rt2.bottom)/ Xdpi * 2.54]);
+ Result := L1+#13+T1+#13+R1+#13+B1;
+ end;
+ end;
+end;
+
+
+Procedure ShowKeyinRect(ISB:TImageScrollBox;iRect:TRect); //顯示登打位置
+var
+ XZoom : Single;
+ YZoom : Single;
+ newZoom : Single;
+ x1,x2,y1,y2 : Integer;
+ theRect : Trect;
+ Bmp : TBitmap;
+ FAnnotationCanvas : TCanvas;
+ i : Integer;
+begin
+ Therect:= iRect;
+ XZoom := ( (ISB.Width-20)/(Therect.Right - Therect.Left + 1) ) * 100;
+ YZoom := ( (ISB.Height-20)/(Therect.Bottom - Therect.Top + 1+40)) * 100;
+
+ { limit the zoom value to 1000 % }
+ newZoom := MinFloat(MinFloat(XZoom,100), YZoom) ;
+ //NewZoom := ISB.ZoomPercent;
+ ISB.ZoomPercent := newZoom ;
+
+ ISB.HorzScrollBar.Position := SafeTrunc(Therect.Left* newZoom /100 );
+ ISB.VertScrollBar.Position := SafeTrunc((Therect.Top-20) * newZoom /100 );
+ //加入區域底色
+ x1 := SafeTrunc(Therect.Left* newZoom /100 )-ISB.HorzScrollBar.Position;
+ x2 := SafeTrunc(Therect.Right* newZoom /100 )-ISB.HorzScrollBar.Position;
+ y1 := SafeTrunc(Therect.Top* newZoom /100 )-ISB.VertScrollBar.Position;
+ y2 := SafeTrunc(Therect.bottom* newZoom /100 )-ISB.VertScrollBar.Position;
+ FAnnotationCanvas := TCanvas.Create;
+ FAnnotationCanvas.Handle := GetDC( ISB.Handle );
+ FAnnotationCanvas.Pen.Style := psSolid;
+ FAnnotationCanvas.Pen.Color := $00FEFAAD; //&H80000005//65535;
+ FAnnotationCanvas.Pen.Width := 1;
+ FAnnotationCanvas.Pen.Mode := pmMask;
+
+ { Draw box on screen }
+ for i := y1 to y2 do begin
+ FAnnotationCanvas.MoveTo( x1, i );
+ FAnnotationCanvas.LineTo( x2, i );
+ end;
+ ReleaseDC(0,FAnnotationCanvas.Handle);
+ FAnnotationCanvas.Free;
+
+end;
+
+procedure ImageResize(Graphic:TDibGraphic;DesWidth,DesHeight:Integer);
+var
+ Transform : TResizeTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ Transform := TResizeTransform.Create;
+ try
+ Transform.Width := DesWidth;
+ Transform.Height := DesHeight;
+ //Transform.Interpolated := True;
+ //Transform.Filter := ifLanczos3;
+ FUndoGraphic.Assign(Graphic);
+ Transform.ApplyOnDest(FUndoGraphic,Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+end;
+
+Procedure DpiResize(Graphic:TDibGraphic;DesDpi:Integer;CheckDpi:Boolean); //Dpi不足時放大Size
+Var
+ NewWidth : Integer;
+ NewHeight : Integer;
+begin
+ if CheckDpi then //CUB 出現Dpi是1 要用這個才不會出現out of resource
+ begin
+ if (Graphic.XDotsPerInch > DesDpi) and (Graphic.YDotsPerInch> DesDpi) then
+ begin
+ NewWidth := Round(Graphic.Width * (DesDpi / Graphic.XDotsPerInch));
+ NewHeight := Round(Graphic.Height * (DesDpi / Graphic.YDotsPerInch));
+ Graphic.XDotsPerInch := DesDpi;
+ Graphic.YDotsPerInch := DesDpi;
+ ImageResize(Graphic,NewWidth,NewHeight);
+ end;
+ end
+ Else //永豐傳真一定要用到這一段
+ begin
+ NewWidth := Round(Graphic.Width * (DesDpi / Graphic.XDotsPerInch));
+ NewHeight := Round(Graphic.Height * (DesDpi / Graphic.YDotsPerInch));
+ Graphic.XDotsPerInch := DesDpi;
+ Graphic.YDotsPerInch := DesDpi;
+ ImageResize(Graphic,NewWidth,NewHeight);
+ end;
+
+end;
+
+Procedure DrawPointLine(ISB:TImageScrollBox;UpPointL,UpPointR,DownPointL:TPoint); //畫十字位置
+begin
+ ISB.DisplayedGraphic.Canvas.pen.Color := clGreen;
+ ISB.DisplayedGraphic.Canvas.Font.Size := 16;
+
+ //左上
+ ISB.DisplayedGraphic.Canvas.MoveTo(0,0);
+ ISB.DisplayedGraphic.Canvas.LineTo(Round(uppointL.X*ISB.ZoomPercent/100),Round(uppointL.y*ISB.ZoomPercent/100));
+
+ //左下
+ ISB.DisplayedGraphic.Canvas.MoveTo(0,Round(ISB.Graphic.Height*ISB.ZoomPercent/100));
+ ISB.DisplayedGraphic.Canvas.LineTo(Round(downpointL.X*ISB.ZoomPercent/100),Round(downpointL.y*ISB.ZoomPercent/100));
+
+ //右上
+ ISB.DisplayedGraphic.Canvas.MoveTo(Round(ISB.Graphic.Width*ISB.ZoomPercent/100),0);
+ ISB.DisplayedGraphic.Canvas.LineTo(Round(uppointR.X*ISB.ZoomPercent/100),Round(uppointR.y*ISB.ZoomPercent/100));
+
+ //ISB.DisplayedGraphic.Canvas.MoveTo(Round(ImageScrollBox1.Graphic.Width*ImageScrollBox1.ZoomPercent/100),Round(ImageScrollBox1.Graphic.Height*ImageScrollBox1.ZoomPercent/100));
+ //ISB.DisplayedGraphic.Canvas.LineTo(Round(downpointR.X*ImageScrollBox1.ZoomPercent/100),Round(downpointR.y*ImageScrollBox1.ZoomPercent/100));
+end;
+
+Procedure Color2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer); //用RTS彩色轉黑白
+var
+ bmp:TBitmap;
+ Xdpi,Ydpi : Integer;
+begin
+ XDpi := ISB.Graphic.XDotsPerInch;
+ YDpi := ISB.Graphic.YDotsPerInch;
+ bmp := TBitmap.Create;
+ try
+ bmp.Assign(ISB.Graphic);
+ BmpGoVrs_Color(bmp,Para1,para2,para3);
+ ISB.Graphic.Assign(bmp);
+
+ ISB.Graphic.XDotsPerInch := XDpi;
+ ISB.Graphic.YDotsPerInch := YDpi;
+ Finally
+ bmp.Free;
+ end;
+end;
+
+Procedure Color2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer;Part:Trect); Overload; //用RTS彩色轉黑白
+var
+ bmp:TBitmap;
+ Xdpi,Ydpi : Integer;
+begin
+ XDpi := ISB.Graphic.XDotsPerInch;
+ YDpi := ISB.Graphic.YDotsPerInch;
+ bmp := TBitmap.Create;
+ try
+ bmp.Assign(ISB.Graphic);
+ BmpGoVrs_Color(bmp,Para1,para2,para3);
+ ISB.Graphic.Assign(bmp);
+
+ ISB.Graphic.XDotsPerInch := XDpi;
+ ISB.Graphic.YDotsPerInch := YDpi;
+ Finally
+ bmp.Free;
+ end;
+end;
+
+Procedure Gray2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer);
+var
+ bmp:TBitmap;
+ Xdpi,Ydpi : Integer;
+begin
+ XDpi := ISB.Graphic.XDotsPerInch;
+ YDpi := ISB.Graphic.YDotsPerInch;
+ bmp := TBitmap.Create;
+ try
+ if ISB.Graphic.ImageFormat <> ifGray256 then
+ Convertto256Gray(ISB.Graphic);
+
+ bmp.Assign(ISB.Graphic);
+ //bmp.PixelFormat := pf8bit; //這樣接影像會拿到 24bit
+ if bmp.PixelFormat = pf8bit then
+ BmpGoVrs(bmp,Para1,para2,para3);
+ if bmp.PixelFormat = pf24bit then
+ BmpGoVrs_Color(bmp,Para1,para2,para3);
+ ISB.Graphic.Assign(bmp);
+
+
+ ISB.Graphic.XDotsPerInch := XDpi;
+ ISB.Graphic.YDotsPerInch := YDpi;
+ Finally
+ bmp.Free;
+ end;
+end;
+
+Procedure Gray2BW_RTS(ISB:TImageScrollBox;Para1,Para2,Para3:Integer;Part:Trect); Overload; //用RTS灰階轉黑白
+var
+ bmp:TBitmap;
+ Xdpi,Ydpi : Integer;
+begin
+ XDpi := ISB.Graphic.XDotsPerInch;
+ YDpi := ISB.Graphic.YDotsPerInch;
+ bmp := TBitmap.Create;
+ try
+
+ bmp.Assign(ISB.Graphic);
+ bmp.PixelFormat := pf8bit;
+ BmpGoVrs(bmp,Para1,para2,para3,Part);
+ ISB.Graphic.Assign(bmp);
+
+
+ ISB.Graphic.XDotsPerInch := XDpi;
+ ISB.Graphic.YDotsPerInch := YDpi;
+ Finally
+ bmp.Free;
+ end;
+end;
+
+procedure Emboss(ISB:TImageScrollBox);
+var
+ Transform : TEmbossTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(ISB.Graphic);
+ Transform := TEmbossTransform.Create;
+ try
+ Transform.ApplyOnDest(FUndoGraphic, ISB.Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+ //ISB.Redraw(True);
+end;
+
+Procedure BrightnessImg(ISB:TImageScrollBox;Precent:Integer); //調整亮度
+var
+ Transform : TBrightnessTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(ISB.Graphic);
+ Transform := TBrightnessTransform.Create;
+ try
+ Transform.Percent := Precent;
+ Transform.ApplyOnDest(FUndoGraphic, ISB.Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+ //ImageScrollBox.Redraw(True);
+end;
+
+Procedure ConvertToBW(Graphic : TDibGraphic); //轉成黑白
+var
+ Transform : TImageFormatTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ Transform := TImageFormatTransform.Create;
+ FUndoGraphic := TDibGraphic.Create;
+ try
+ FUndoGraphic.Assign(Graphic);
+ Transform.ImageFormat := ifBlackWhite;
+ Transform.Quantize := True;
+ Transform.Dither := False;
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+end;
+
+Procedure ConvertTo256Gray(Graphic : TDibGraphic); //轉成256灰階
+var
+ Transform : TImageFormatTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ Transform := TImageFormatTransform.Create;
+ FUndoGraphic := TDibGraphic.Create;
+ try
+ FUndoGraphic.Assign(Graphic);
+ Transform.ImageFormat := ifGray256;
+ Transform.Quantize := True;
+ Transform.Dither := False;
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+end;
+
+Procedure ClearLine(Graphic : TDibGraphic;bt:Integer); //清影像上的線條
+Var
+ GraphicA : TTiffGraphic;
+ i:integer;
+begin
+ GraphicA := TTiffGraphic.create;
+ Try
+ GraphicA.Assign(Graphic);
+
+ For i:=8 to GraphicA.height-8 do
+ MpsClearLineV(Graphic, GraphicA , i, 1,GraphicA.Width-1,bt );
+
+ For i:=8 to GraphicA.Width-8 do
+ MpsClearLineH(Graphic, GraphicA , i, 1,GraphicA.Height-1,bt );
+ Graphic.Assign(GraphicA);
+ Finally
+ GraphicA.Free;
+ end;
+
+end;
+
+procedure CropImg(Graphic : TDibGraphic;iRect:TRect);
+var
+ Transform : TCropTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(Graphic);
+ Transform := TCropTransform.Create;
+ Transform.CropMode := cmExtractRect;
+ try
+ Transform.Left := iRect.Left;
+ Transform.Right := iRect.Right;
+ Transform.Top := iRect.Top;
+ Transform.Bottom := iRect.Bottom;
+
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+end;
+
+Function GetPosAngle(UpL,DownL,UpR:TPoint):Single; //取二直線夾角角度
+var
+ angle1,angle2 : Single;
+ Wseg,Lseg : Integer;
+begin
+ Wseg := DownL.Y - UpL.Y;
+ Lseg := UpL.X - DownL.X;
+ Angle1 := (Arctan(Lseg/Wseg)*180/pi);
+
+ Wseg := UpL.Y - UpR.Y;
+ Lseg := UpR.X - UpL.X;
+ Angle2 := (Arctan(Wseg/Lseg)*180/pi);
+ Result := 90 +(Angle1)+(Angle2);
+end;
+
+function CheckSize(ISB:TImageScrollBox;UpL,UpR,DownL:TPoint;DefWidth,DefHeight:String): WideString; //檢查Size並縮放
+var
+ NowW,NowH : Integer;
+ DefW,DefH : Integer;
+ SizeW,SizeH : Integer;
+ ReSizeW,ReSizeH : Integer;
+ XDpi,YDpi : Integer;
+begin
+ Result := '';
+ XDpi := ISB.Graphic.XDotsPerInch;
+ YDpi := ISB.Graphic.YDotsPerInch;
+ DefW := Round(strtofloat(DefWidth)/2.54*XDpi);
+ DefH := Round(strtofloat(DefHeight)/2.54*XDpi);
+ SizeW := ISB.Graphic.Width;
+ SizeH :=ISB.Graphic.Height;
+ IF (DefW > 0) and (DefH > 0) and ((GetPosAngle(UpL,DownL,UpR) > 89) and (GetPosAngle(UpL,DownL,UpR) < 91)) Then
+ begin
+ NowW := UpR.X - UpL.X;
+ NowH := DownL.Y - UpL.Y;
+ If (NowW <> ISB.Graphic.Width) and (NowH <> ISB.Graphic.Height) and ((NowW <> DefW) or (NowH <> DefH)) then
+ begin
+ ReSizeW := Round(ISB.Graphic.Width * DefW / NowW);
+ ReSizeH := Round(ISB.Graphic.Height * DefH /NowH);
+ ImageResize(ISB.Graphic,ReSizeW,ReSizeH);
+ ISB.Redraw(True);
+ Result := '原長'+inttostr(SizeH)+',原寬'+inttostr(SizeW)+',長變動'+inttostr(ReSizeH)+',寬變動'+inttostr(ReSizeW);
+ end;
+ end;
+end;
+
+Function GetPixBW( srcGraphic : TDibGraphic; x,y:integer ):integer;
+{******************************************************************************}
+{ 取點的顏色 要用黑白的 }
+{******************************************************************************}
+var
+
+ pSrcByte : ^Byte;
+ srcBit : Byte;
+
+
+begin
+
+ result := 1;
+ pSrcByte := Addr( srcGraphic.ScanLine[ y ] ^ [ x div 8 ] );
+ srcBit := $80 shr ( x mod 8 );
+
+ result := (pSrcByte^ and srcBit);
+ if result > 0 Then result := 0
+ else result := 1;
+
+end;
+
+Procedure BMPConverJpg(Source,SaveFileName:STring); //Bmp轉jpeg
+var
+ ConvertJpg :TTiffGraphic;
+ BMP : TBitMap ;
+begin
+ ConvertJpg:=TTiffGraphic.Create;
+ BMP :=TBitmap.Create;
+ try
+ BMP.LoadFromFile(source);
+ ConvertJpg.Assign(BMP);
+ ConvertJpg.Compression := tcNone;
+ ConvertJpg.SaveToFile(SaveFileName);
+ finally
+ convertjpg.Free;
+ Bmp.Free;
+ end;
+end;
+
+Procedure BWTif2Jpg(Graphic:TDibGraphic); //黑白Tif轉彩色jpg
+var
+ JpgGraphic : TJpegGraphic;
+ FUndoGraphic : TDibGraphic;
+ Transform : TImageFormatTransform;
+begin
+ JpgGraphic := TJpegGraphic.Create;
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(Graphic);
+ Transform := TImageFormatTransform.Create;
+ try
+ Transform.ImageFormat := ifTrueColor;
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+
+ end;
+ FUndoGraphic.Free;
+end;
+
+Procedure Convert2Jpg(Graphic:TDibGraphic); //黑白Tif轉彩色jpg
+var
+ FUndoGraphic : TDibGraphic;
+ Transform : TImageFormatTransform;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(Graphic);
+ Transform := TImageFormatTransform.Create;
+ try
+ Transform.ImageFormat := ifTrueColor;
+ Transform.ApplyOnDest(FUndoGraphic, Graphic);
+ finally
+ Transform.Free;
+
+ end;
+ FUndoGraphic.Free;
+end;
+
+Procedure FieldMask(ISB:TImageScrollBox;SiteList,Mode: WideString;UpPointL:TPoint); //遮罩 Mode:mark mask
+var
+ i,Dpi : integer;
+ Site_List,SiteStr : TStringlist;
+ L,T,R,B :String;
+ TB,LR : Integer;
+ Ann : String;
+ FixB : integer;
+begin
+ ISB.AlwaysShowAnnotations:= false;
+ ISB.MouseMode := mmuser;
+ ISB.MouseMode := mmselect;
+ Dpi := ISB.Graphic.XDotsPerInch;
+ FixB := Round(1/2.54*Dpi);
+ Site_List := TStringlist.Create;
+ SiteStr := TStringlist.Create;
+ try
+ Ann := '';
+ Site_List.Text:=SiteList;
+ For i := 0 to Site_List.Count -1 do
+ begin
+ SiteStr.CommaText := Site_List.Strings[i];
+ L := inttostr(Round(Strtofloat(SiteStr[0])/2.54*Dpi)+UpPointL.x);
+ T := inttostr(Round(Strtofloat(SiteStr[1])/2.54*Dpi)+UpPointL.y);
+ R := inttostr(Round(Strtofloat(SiteStr[2])/2.54*Dpi)+UpPointL.x);
+ B := inttostr(Round(Strtofloat(SiteStr[3])/2.54*Dpi)+UpPointL.y);
+ TB := strtoint(B) - strtoint(T);
+ LR := strtoint(R) - strtoint(L);
+
+ If strtoint(L) < 0 then //因為十字損壞,抓不到正確的位置,另外做判斷
+ begin
+ L := '0';
+ R := inttostr(LR);
+ end;
+ if strtoint(T) < 0 then
+ begin
+ T := '0';
+ B := inttostr(TB);
+ end;
+ if strtoint(R) > ISB.Graphic.Width then
+ begin
+ R := inttostr(ISB.Graphic.Width);
+ L := inttostr(ISB.Graphic.Width-LR);
+ end;
+ if strtoint(B) > ISB.Graphic.Height then
+ begin
+ B := inttostr(ISB.Graphic.Height-FixB);
+ T := inttostr(ISB.Graphic.Height-FixB-TB);
+ end;
+
+ if Mode = 'Mask' then
+ Ann := Ann+'(2)('+L+')('+T+')('+R+')('+B+')(1)($FFFFFF)(0)(1)(4)'
+ Else if Mode = 'Mark' Then
+ Ann := Ann+'(2)('+L+')('+T+')('+R+')('+B+')(1)($00FEFAAD)(1)(1)(4)'
+ end;
+ If Ann <> '' Then
+ Ann := '('+inttostr(Site_List.Count)+')'+Ann;
+ ISB.Annotations := Ann;
+ If Ann <> '' Then
+ ISB.AlwaysShowAnnotations:= true;
+
+ Finally
+ Site_List.Free;
+ SiteStr.Free;
+ end;
+end;
+
+procedure SaveAnnotation(ISB:TImageScrollBox;FileName: WideString); //遮罩存檔
+Var
+ iISB : TImageScrollBox;
+begin
+ iISB := TImageScrollBox.Create(nil);
+ iISB.Graphic := ISB.Graphic;
+ iISB.Annotations := ISB.Annotations;
+ iISB.AlwaysShowAnnotations := True;
+ iISB.MouseMode := mmAnnotate;
+ iISB.BurnAnnotations;
+ ConvertToBW(iISB.Graphic);
+ iISB.SaveToFile(FileName);
+ iISB.Free;
+end;
+
+Procedure FilterColor(SoISB,DeISB:TImageScrollBox;Ration:Integer); //濾掉顏色 留黑白
+var
+ x,y : integer;
+ xrgb : Trgb;
+begin
+ DeISB.Graphic.NewImage(SoISB.Graphic.Width,SoISB.Graphic.Height,ifTrueColor, SoISB.Graphic.PalettePtr ,SoISB.Graphic.XDotsPerInch,SoISB.Graphic.YDotsPerInch );
+ For y:= 0 to SoISB.Graphic.Height -1 do
+ for x:=0 to SoISB.Graphic.Width -1 do begin
+ xrgb := SoISB.Graphic.RGB[x,y];
+
+ if (xrgb.Red > Ration ) or (xrgb.Green > Ration) or (xrgb.Blue > Ration) then begin
+
+ xrgb.Red := 255;
+ xrgb.Green := 255;
+ xrgb.Blue := 255;
+ DeISB.Graphic.RGB[x,y] := xrgb;
+ //ImageScrollBox3.Graphic.RGB[x,y] := ImageScrollBox2.Graphic.RGB[x,y];
+ end {else begin
+
+ xrgb.Red := 255;
+ xrgb.Green := 255;
+ xrgb.Blue := 255;
+ ImageScrollBox3.Graphic.RGB[x,y] := xrgb;
+ end;}
+
+ end;
+
+ DeISB.Redraw(True);
+
+end;
+
+procedure JpgReSize_Exif(Maxlength,Quality:integer;OldFile,NewFile:String;WaterGraphic:TGraphic;PrintDate:Boolean); //照片縮放包含Exif
+var
+ ImgData:TImgData;
+ Orig,Smaller:tjpegimage;
+ buffer:tbitmap;
+ IH,IW,TH,TL : Integer;
+begin
+ IH := 0;
+ if WaterGraphic <> nil then
+ begin
+ IW := 80;
+ IH := Round(WaterGraphic.Height*IW/WaterGraphic.Width);
+ end;
+ TH := IH + 5;
+ TL := 5;
+ Buffer := tbitmap.Create;
+ Orig := tjpegImage.Create;
+ Smaller := tjpegimage.create;
+ ImgData := TimgData.Create;
+ try
+ //Orig.LoadFromFile(ExtractFilepath(ImgData.Filename)+'\222.jpg');
+ ImgData.BuildList := GenAll; // on by default anyway
+ ImgData.ProcessFile(OldFile);
+
+ Orig.LoadFromFile(ImgData.Filename);
+ Orig.DIBNeeded;
+ Buffer.PixelFormat := pf24bit;
+ IF (Orig.Width >= Orig.Height) and (Orig.Width > MaxLength) Then
+ begin
+ Buffer.Width := MaxLength;
+ Buffer.Height := Round(Orig.Height * MaxLength / Orig.Width);
+ end
+ Else IF (Orig.Height > Orig.Width) and (Orig.Width > MaxLength) Then
+ begin
+ Buffer.Height := MaxLength;
+ Buffer.Width := Round(Orig.Width * MaxLength / Orig.Height);
+ end
+ Else
+ begin
+ Buffer.Height := Orig.Height;
+ Buffer.Width := Orig.Width;
+ end;
+ // Simple resize
+ Buffer.Canvas.StretchDraw(rect(0,0,Buffer.Width,Buffer.Height),Orig);
+ Buffer.Canvas.CopyMode := SRCAND;
+ if WaterGraphic <> nil then
+ begin
+ WaterGraphic.Transparent := True;
+ Buffer.Canvas.StretchDraw(Rect(0,0,IW,IH),WaterGraphic);
+ end;
+ //image1.Picture.Graphic.Transparent := True;
+ //Buffer.Canvas.StretchDraw(Rect(0,0,IW,IH),image1.Picture.Graphic);
+ IF PrintDate and ImgData.HasExif then
+ begin
+ Buffer.Canvas.Font.Size := 16;
+ Buffer.Canvas.Font.Color := clRed;
+ Buffer.Canvas.Pen.Mode := pmMerge;
+ Buffer.Canvas.Pen.Style := psClear;
+ Buffer.Canvas.Brush.Style := bsClear;
+ Buffer.Canvas.TextOut(TL,TH,imgdata.ExifObj.DateTime);
+ end;
+
+ Smaller.Assign(Buffer);
+ Smaller.CompressionQuality := Quality; //75;
+ Smaller.Compress;
+ IF ImgData.HasExif then
+ begin
+ imgdata.WriteEXIFJpeg(Smaller,NewFile);
+ end
+ Else
+ begin
+ Smaller.SaveToFile(NewFile);
+ end;
+ finally // Cleanup
+ Buffer.free;
+ Orig.Free;
+ SMaller.Free;
+ ImgData.Free;
+ end;
+end;
+
+Function GetExif_CaptureDateTime(FileName : String):String; //取出檔案裡的Exif拍攝日期
+var
+ ImgData:TImgData;
+begin
+ Result := '';
+ ImgData := TimgData.Create;
+ try
+ ImgData.BuildList := GenAll; // on by default anyway
+ ImgData.ProcessFile(FileName);
+ if ImgData.HasExif then
+ Result := ImgData.ExifObj.DateTime;
+ finally
+ ImgData.Free;
+ end;
+end;
+
+procedure SetKeyinRect_New( ISB:TImageScrollBox; SiteStr, SiteStr_Black,FormHeight: String; UpPointL,UpPointR:TPoint);
+var Rt:Trect;
+ XDpi,YDpi : single;
+ x1,y1,x2,y2 : Integer;
+ XZoom : Single;
+ YZoom : Single;
+ newZoom : Single;
+ theRect,ckRect : Trect;
+ Bmp : TBitmap;
+ FAnnotationCanvas : TCanvas;
+ i : Integer;
+ L,T,R,B : String;
+ L1,T1,R1,B1 : String;
+ S,S1 : TStringlist;
+ FormH : Integer;
+ IngronDis : Integer;
+begin
+ S := TStringlist.Create;
+ S1 := TStringlist.Create;
+ try
+ S.CommaText := Sitestr;
+ L := S.Strings[0];
+ T := S.Strings[1];
+ R := S.Strings[2];
+ B := S.Strings[3];
+ If SiteStr_Black <> '' Then
+ begin
+ S1.CommaText := SiteStr_Black;
+ L1 := S1.Strings[0];
+ T1 := S1.Strings[1];
+ R1 := S1.Strings[2];
+ B1 := S1.Strings[3];
+ end;
+ finally
+ S.Free;
+ end;
+ //If ISB.FileName = '' Then Exit;
+ If (ISB.Hint = '') and (ISB.FileName = '') Then Exit; //因玉山影像放在Memory裡需使用 hint 來記檔名
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ IngronDis := Round(0.8 /2.54 * Xdpi); //內容與十字最少要有的距離 先訂1公分
+ ISB.Refresh;
+ If FormHeight <> '' Then
+ FormH := Round(strtoFloat(FormHeight)/2.54*Xdpi)+UpPointL.Y
+ Else
+ FormH := 0;
+ //Therect:=Rect(Round(strtoFloat(L)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y,Round(strtoFloat(R)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ //ckRect :=Rect(Round(strtoFloat(L)/2.54*Xdpi)+UpPointL.X-50,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y,Round(strtoFloat(R)/2.54*Xdpi)+UpPointL.X+50,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ ckRect :=Rect(UpPointL.X,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y+5,UpPointR.X,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ //showmessage(inttostr(ckrect.Left)+#13+inttostr(ckrect.Top)+#13+inttostr(ckrect.Right)+#13+inttostr(ckrect.Bottom)+#13+inttostr(Get_OMR(ckRect,ImageScrollBox1.Graphic)));
+
+ //IF (BlackPoint.X >0) and (BlackPoint.Y >0) and (SiteStr_Black <>'') and (FormH > 0) and ((Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y+IngronDis >= FormH) or (Get_OMR(ckRect,ImageScrollBox1.Graphic)<100)) {(Round(strtoFloat(T)/2.54*Xdpi) >= (9.3*Xdpi))} Then
+ //begin
+ //Therect:=Rect(BlackPoint.X-Round(strtoFloat(L1)/2.54*Xdpi),BlackPoint.Y -Round(strtoFloat(T1)/2.54*Xdpi),BlackPoint.X-Round(strtoFloat(R1)/2.54*Xdpi),BlackPoint.Y-Round(strtoFloat(B1)/2.54*Xdpi));
+ //Showmessage(inttostr(BlackPoint.X)+#13+inttostr(BlackPoint.Y)+#13+inttostr(Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y)+'-->'+inttostr(IngronDis)+'-->'+inttostr(FormH)+#13+inttostr(Get_OMR(ckRect,ImageScrollBox1.Graphic)));
+ {end
+ else
+ begin }
+ Therect:=Rect(Round(strtoFloat(L)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y,Round(strtoFloat(R)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ //end;
+ XZoom := ( (ISB.Width-20)/(Therect.Right - Therect.Left + 0.3*XDpi) ) * 100;
+ YZoom := ( (ISB.Height-20)/(Therect.Bottom - Therect.Top + 0.3*YDpi)) * 100;
+
+ { limit the zoom value to 1000 % }
+ newZoom := MinFloat(MinFloat(XZoom,100), YZoom) ;
+ ISB.ZoomPercent := newZoom ;
+
+
+ ISB.HorzScrollBar.Position := SafeTrunc(Therect.Left* newZoom /100 )-SafeTrunc(0.3*XDpi* newZoom /100);
+ ISB.VertScrollBar.Position := SafeTrunc((Therect.Top) * newZoom /100 )-SafeTrunc(0.2*YDpi* newZoom /100);
+ //加入區域底色
+ x1 := SafeTrunc(Therect.Left* newZoom /100 )-ISB.HorzScrollBar.Position;
+ x2 := SafeTrunc(Therect.Right* newZoom /100 )-ISB.HorzScrollBar.Position;
+ y1 := SafeTrunc(Therect.Top* newZoom /100 )-ISB.VertScrollBar.Position;
+ y2 := SafeTrunc(Therect.bottom* newZoom /100 )-ISB.VertScrollBar.Position;
+ //Application.ProcessMessages; //當元件時不可亂用這個指令
+ ISB.Refresh;
+ FAnnotationCanvas := TCanvas.Create;
+ FAnnotationCanvas.Handle := GetDC( ISB.Handle );
+ FAnnotationCanvas.Pen.Style := psSolid;
+ FAnnotationCanvas.Pen.Color := $00FEFAAD; //&H80000005//65535;
+ FAnnotationCanvas.Pen.Width := 1;
+ FAnnotationCanvas.Pen.Mode := pmMask;
+
+ { Draw box on screen }
+ for i := y1 to y2 do begin
+ FAnnotationCanvas.MoveTo( x1, i );
+ FAnnotationCanvas.LineTo( x2, i );
+ end;
+ ReleaseDC(0,FAnnotationCanvas.Handle);
+ FAnnotationCanvas.Free;
+
+end;
+
+procedure SetKeyinRect_New( ISB:TImageScrollBox; SiteStr, SiteStr_Black,FormHeight: String; UpPointL,UpPointR:TPoint;SP:TShape); overload;
+var Rt:Trect;
+ XDpi,YDpi : single;
+ x1,y1,x2,y2 : Integer;
+ XZoom : Single;
+ YZoom : Single;
+ newZoom : Single;
+ theRect,ckRect : Trect;
+ Bmp : TBitmap;
+ FAnnotationCanvas : TCanvas;
+ i : Integer;
+ L,T,R,B : String;
+ L1,T1,R1,B1 : String;
+ S,S1 : TStringlist;
+ FormH : Integer;
+ IngronDis : Integer;
+begin
+
+ S := TStringlist.Create;
+ S1 := TStringlist.Create;
+ try
+ S.CommaText := Sitestr;
+ L := S.Strings[0];
+ T := S.Strings[1];
+ R := S.Strings[2];
+ B := S.Strings[3];
+ If SiteStr_Black <> '' Then
+ begin
+ S1.CommaText := SiteStr_Black;
+ L1 := S1.Strings[0];
+ T1 := S1.Strings[1];
+ R1 := S1.Strings[2];
+ B1 := S1.Strings[3];
+ end;
+ finally
+ S.Free;
+ end;
+ //If ISB.FileName = '' Then Exit;
+ if (ISB.Hint = '') and (ISB.FileName = '') then Exit; //因玉山影像放在Memory裡需使用 hint 來記檔名
+
+ XDpi:=ISB.Graphic.XDotsPerInch;
+ YDpi:=ISB.Graphic.YDotsPerInch;
+ IngronDis := Round(0.8 /2.54 * Xdpi); //內容與十字最少要有的距離 先訂1公分
+ ISB.Refresh;
+ If FormHeight <> '' Then
+ FormH := Round(strtoFloat(FormHeight)/2.54*Xdpi)+UpPointL.Y
+ Else
+ FormH := 0;
+ //Therect:=Rect(Round(strtoFloat(L)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y,Round(strtoFloat(R)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ //ckRect :=Rect(Round(strtoFloat(L)/2.54*Xdpi)+UpPointL.X-50,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y,Round(strtoFloat(R)/2.54*Xdpi)+UpPointL.X+50,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ ckRect :=Rect(UpPointL.X,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y+5,UpPointR.X,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ //showmessage(inttostr(ckrect.Left)+#13+inttostr(ckrect.Top)+#13+inttostr(ckrect.Right)+#13+inttostr(ckrect.Bottom)+#13+inttostr(Get_OMR(ckRect,ImageScrollBox1.Graphic)));
+
+ //IF (BlackPoint.X >0) and (BlackPoint.Y >0) and (SiteStr_Black <>'') and (FormH > 0) and ((Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y+IngronDis >= FormH) or (Get_OMR(ckRect,ImageScrollBox1.Graphic)<100)) {(Round(strtoFloat(T)/2.54*Xdpi) >= (9.3*Xdpi))} Then
+ //begin
+ //Therect:=Rect(BlackPoint.X-Round(strtoFloat(L1)/2.54*Xdpi),BlackPoint.Y -Round(strtoFloat(T1)/2.54*Xdpi),BlackPoint.X-Round(strtoFloat(R1)/2.54*Xdpi),BlackPoint.Y-Round(strtoFloat(B1)/2.54*Xdpi));
+ //Showmessage(inttostr(BlackPoint.X)+#13+inttostr(BlackPoint.Y)+#13+inttostr(Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y)+'-->'+inttostr(IngronDis)+'-->'+inttostr(FormH)+#13+inttostr(Get_OMR(ckRect,ImageScrollBox1.Graphic)));
+ {end
+ else
+ begin }
+ Therect:=Rect(Round(strtoFloat(L)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(T)/2.54*Xdpi)+UpPointL.Y,Round(strtoFloat(R)/2.54*Xdpi)+UpPointL.X,Round(strtoFloat(B)/2.54*Xdpi)+UpPointL.Y);
+ //end;
+ XZoom := ( (ISB.Width-20)/(Therect.Right - Therect.Left + 0.3*XDpi) ) * 100;
+ YZoom := ( (ISB.Height-20)/(Therect.Bottom - Therect.Top + 0.3*YDpi)) * 100;
+
+ { limit the zoom value to 1000 % }
+ newZoom := MinFloat(MinFloat(XZoom,100), YZoom) ;
+ ISB.ZoomPercent := newZoom ;
+ if ISB.ZoomPercent < 100 then
+ ISB.AntiAliased := True;
+
+ ISB.HorzScrollBar.Position := SafeTrunc(Therect.Left* newZoom /100 )-SafeTrunc(0.3*XDpi* newZoom /100);
+ ISB.VertScrollBar.Position := SafeTrunc((Therect.Top) * newZoom /100 )-SafeTrunc(0.2*YDpi* newZoom /100);
+ //加入區域底色
+ x1 := SafeTrunc(Therect.Left* newZoom /100 )-ISB.HorzScrollBar.Position;
+ x2 := SafeTrunc(Therect.Right* newZoom /100 )-ISB.HorzScrollBar.Position;
+ y1 := SafeTrunc(Therect.Top* newZoom /100 )-ISB.VertScrollBar.Position;
+ y2 := SafeTrunc(Therect.bottom* newZoom /100 )-ISB.VertScrollBar.Position;
+ //Application.ProcessMessages; //當元件時不可亂用這個指令
+ ISB.Refresh;
+ sp.Brush.Color :=$00FEFAAD;
+ sp.Parent := ISB;
+ sp.Pen.Style := psSolid;
+ sp.Pen.Color := $00FEFAAD;
+ sp.Pen.Width := 1;
+ sp.Pen.Mode := pmMask;
+ sp.Left := x1;
+ sp.Top := y1;
+ sp.Width := x2-x1;
+ sp.Height := y2-y1;
+
+ {FAnnotationCanvas := TCanvas.Create;
+ FAnnotationCanvas.Handle := GetDC( ISB.Handle );
+ FAnnotationCanvas.Pen.Style := psSolid;
+ FAnnotationCanvas.Pen.Color := $00FEFAAD; //&H80000005//65535;
+ FAnnotationCanvas.Pen.Width := 1;
+ FAnnotationCanvas.Pen.Mode := pmMask;}
+
+ { Draw box on screen }
+ {for i := y1 to y2 do begin
+ FAnnotationCanvas.MoveTo( x1, i );
+ FAnnotationCanvas.LineTo( x2, i );
+ end;
+ ReleaseDC(0,FAnnotationCanvas.Handle);
+ FAnnotationCanvas.Free; }
+
+end;
+
+Procedure Image_Smooth(Graphic:TDibGraphic);
+var
+ Transform : TSmoothTransform;
+ FUndoGraphic : TDibGraphic;
+begin
+ FUndoGraphic := TDibGraphic.Create;
+ FUndoGraphic.Assign(Graphic);
+ Transform := TSmoothTransform.Create;
+ try
+ Transform.ApplyOnDest(FUndoGraphic,Graphic);
+ finally
+ Transform.Free;
+ FUndoGraphic.Free;
+ end;
+end;
+
+/// FileName 傳入多筆換行字串
+procedure PrintImg(FileName, LoginID, Datetime,Path: WideString;WaterBmp:TBitmap);
+var
+ PrintMode : TEnvisionPrintMode;
+ GraphicPrinter : TDibGraphicPrinter;
+ PrtDialog : TPrintDialog;
+ S : TStringlist;
+ i,Pages,Page : Integer;
+ Prt_String : String;
+ Prt_H : Integer;
+ ISB : TImageScrollBox;
+ procedure PrintWithManualPrintJob(LoginID,DateTime:String;Pages,Page:Integer);
+ begin
+ If Page = 1 Then
+ begin
+ { if UsePrintJob is False, Printer.BeginDoc and Printer.EndDoc must be
+ called by the user. This allows printing multiple images in the
+ same job (or page). }
+ GraphicPrinter.UsePrintJob := False;
+
+ { if UsePrintJob is False, the print job name that appears in the
+ print manager must be specified in using the Title property of the
+ Printer object. Otherwise, if UsePrintJob is True, the Title
+ property of the TDibGraphicPrinter object is used to specify the
+ job name. }
+ Printer.Title := '影像列印';
+ end;
+
+ IF (Page mod 2) = 1 Then
+ Printer.BeginDoc
+ Else
+ Printer.NewPage;
+
+ ISB.Graphic.Canvas.Font.PixelsPerInch := ISB.Graphic.XDotsPerInch;
+ ISB.Graphic.Canvas.Font.Size := 10;
+
+ ISB.Graphic.Canvas.TextOut(20,20, 'Print User:'+LoginID+' '+'Date:'+DateTime);
+
+ GraphicPrinter.Print(ISB.Graphic);
+
+
+ { this shows how to print text on a page.
+ Printer.Canvas.TextOut(10,10, 'Envision Image Library');
+ }
+ If ((Page mod 2) = 0) or (Page = pages) Then
+ Printer.EndDoc;
+ end;
+
+ procedure PrintWithAutoPrintJob;
+ begin
+ GraphicPrinter.UsePrintJob := True;
+ GraphicPrinter.Title := '影像列印';
+ GraphicPrinter.Print(ISB.Graphic);
+ end;
+
+begin
+ ISB := TImageScrollBox.Create(nil);
+ S := TStringlist.Create;
+ GraphicPrinter := TDibGraphicPrinter.Create;
+ PrtDialog := TPrintDialog.Create(nil);
+ try
+ IF PrtDialog.Execute Then
+ begin
+ S.Text := FileName;
+ Pages := S.Count;
+
+ for i := 0 to S.Count -1 do
+ begin
+ ISB.LoadFromFile(Path+S.Strings[i],1);
+
+
+ if WaterBmp <> nil then
+ watermark2(WaterBmp,70,'',ISB.Graphic);
+ PrintWithManualPrintJob(LoginID,DateTime,Pages,i+1);
+ end;
+ end;
+
+ Finally
+ ISB.Free;
+ PrtDialog.Free;
+ GraphicPrinter.Free;
+ S.Free;
+ end;
+end;
+
+
+// Spec_Page :指定分批頁數,傳0則所有影像一次傳送
+procedure PrintImg(FileName, LoginID, Datetime,Path: WideString;WaterBmp:TBitmap;Spec_Page:Integer);
+var
+ PrintMode : TEnvisionPrintMode;
+ GraphicPrinter : TDibGraphicPrinter;
+ PrtDialog : TPrintDialog;
+ S : TStringlist;
+ i,Pages,Page : Integer;
+ Prt_String : String;
+ Prt_H : Integer;
+ ISB : TImageScrollBox;
+ procedure PrintWithManualPrintJob(LoginID,DateTime:String;Pages,Page:Integer);
+ begin
+ If Page = 1 Then
+ begin
+ { if UsePrintJob is False, Printer.BeginDoc and Printer.EndDoc must be
+ called by the user. This allows printing multiple images in the
+ same job (or page). }
+ GraphicPrinter.UsePrintJob := False;
+
+ { if UsePrintJob is False, the print job name that appears in the
+ print manager must be specified in using the Title property of the
+ Printer object. Otherwise, if UsePrintJob is True, the Title
+ property of the TDibGraphicPrinter object is used to specify the
+ job name. }
+ Printer.Title := '影像列印';
+ end;
+
+ IF ((Spec_Page > 0) and ((Page mod Spec_Page) = 1)) or ((Spec_Page=0) and (page=1)) Then
+ Printer.BeginDoc
+ Else
+ Printer.NewPage;
+
+ ISB.Graphic.Canvas.Font.PixelsPerInch := ISB.Graphic.XDotsPerInch;
+ ISB.Graphic.Canvas.Font.Size := 10;
+
+ ISB.Graphic.Canvas.TextOut(20,20, 'Print User:'+LoginID+' '+'Date:'+DateTime);
+
+ GraphicPrinter.Print(ISB.Graphic);
+
+
+ { this shows how to print text on a page.
+ Printer.Canvas.TextOut(10,10, 'Envision Image Library');
+ }
+ If ((Spec_Page > 0) and ((Page mod Spec_Page) = 0)) or (Page = pages) Then
+ Printer.EndDoc;
+ end;
+
+ procedure PrintWithAutoPrintJob;
+ begin
+ GraphicPrinter.UsePrintJob := True;
+ GraphicPrinter.Title := '影像列印';
+ GraphicPrinter.Print(ISB.Graphic);
+ end;
+
+begin
+ ISB := TImageScrollBox.Create(nil);
+ S := TStringlist.Create;
+ GraphicPrinter := TDibGraphicPrinter.Create;
+ PrtDialog := TPrintDialog.Create(nil);
+ try
+ IF PrtDialog.Execute Then
+ begin
+ S.Text := FileName;
+ Pages := S.Count;
+
+ for i := 0 to S.Count -1 do
+ begin
+ ISB.LoadFromFile(Path+S.Strings[i],1);
+
+
+ if WaterBmp <> nil then
+ watermark2(WaterBmp,70,'',ISB.Graphic);
+ PrintWithManualPrintJob(LoginID,DateTime,Pages,i+1);
+ end;
+ end;
+
+ Finally
+ ISB.Free;
+ PrtDialog.Free;
+ GraphicPrinter.Free;
+ S.Free;
+ end;
+end;
+
+procedure PrintImg(FileName, LoginID, Datetime,Path: WideString;WaterBmp:TBitmap;Spec_Page:Integer;NeedSetup:Boolean); overload;
+var
+ PrintMode : TEnvisionPrintMode;
+ GraphicPrinter : TDibGraphicPrinter;
+ PrtDialog : TPrintDialog;
+ S : TStringlist;
+ i,Pages,Page : Integer;
+ Prt_String : String;
+ Prt_H : Integer;
+ ISB : TImageScrollBox;
+ procedure PrintWithManualPrintJob(LoginID,DateTime:String;Pages,Page:Integer);
+ begin
+ If Page = 1 Then
+ begin
+ { if UsePrintJob is False, Printer.BeginDoc and Printer.EndDoc must be
+ called by the user. This allows printing multiple images in the
+ same job (or page). }
+ GraphicPrinter.UsePrintJob := False;
+
+ { if UsePrintJob is False, the print job name that appears in the
+ print manager must be specified in using the Title property of the
+ Printer object. Otherwise, if UsePrintJob is True, the Title
+ property of the TDibGraphicPrinter object is used to specify the
+ job name. }
+ Printer.Title := '影像列印';
+ end;
+
+ IF ((Spec_Page > 0) and ((Page mod Spec_Page) = 1)) or ((Spec_Page=0) and (page=1)) Then
+ Printer.BeginDoc
+ Else
+ Printer.NewPage;
+
+ ISB.Graphic.Canvas.Font.PixelsPerInch := ISB.Graphic.XDotsPerInch;
+ ISB.Graphic.Canvas.Font.Size := 10;
+
+ ISB.Graphic.Canvas.TextOut(20,20, 'Print User:'+LoginID+' '+'Date:'+DateTime);
+
+ GraphicPrinter.Print(ISB.Graphic);
+
+
+ { this shows how to print text on a page.
+ Printer.Canvas.TextOut(10,10, 'Envision Image Library');
+ }
+ If ((Spec_Page > 0) and ((Page mod Spec_Page) = 0)) or (Page = pages) Then
+ Printer.EndDoc;
+ end;
+
+ procedure PrintWithAutoPrintJob;
+ begin
+ GraphicPrinter.UsePrintJob := True;
+ GraphicPrinter.Title := '影像列印';
+ GraphicPrinter.Print(ISB.Graphic);
+ end;
+
+begin
+ ISB := TImageScrollBox.Create(nil);
+ S := TStringlist.Create;
+ GraphicPrinter := TDibGraphicPrinter.Create;
+ PrtDialog := TPrintDialog.Create(nil);
+ try
+ IF (not NeedSetup) or (NeedSetup and PrtDialog.Execute) Then
+ begin
+ S.Text := FileName;
+ Pages := S.Count;
+
+ for i := 0 to S.Count -1 do
+ begin
+ ISB.LoadFromFile(Path+S.Strings[i],1);
+
+
+ if WaterBmp <> nil then
+ watermark2(WaterBmp,70,'',ISB.Graphic);
+ PrintWithManualPrintJob(LoginID,DateTime,Pages,i+1);
+ end;
+ end;
+
+ Finally
+ ISB.Free;
+ PrtDialog.Free;
+ GraphicPrinter.Free;
+ S.Free;
+ end;
+end;
+
+Procedure Color2tif(Graphic:TObject;FileName:String); //彩色影像存Tif
+var
+ TiffGraphic :TTiffGraphic;
+begin
+ TiffGraphic := TTiffGraphic.Create;
+ try
+ if Graphic is TTiffGraphic then
+ TiffGraphic.Assign(TTiffGraphic(Graphic))
+ Else if Graphic is TDibGraphic then
+ TiffGraphic.Assign(TDibGraphic(Graphic))
+ else
+ Showmessage('Format Error');
+
+ if TiffGraphic.ImageFormat = ifBlackWhite then
+ begin
+ TiffGraphic.SaveToFile(FileName);
+ end
+ else
+ begin
+ TiffGraphic.Compression := tcJPEG;
+ TiffGraphic.JpegQuality := 30;
+ TiffGraphic.SaveToFile(FileName);
+ end
+
+ finally
+ TiffGraphic.Free;
+ end;
+end;
+
+
+end.
diff --git a/reassemble/CB_IMGPSScanImp.api.pas b/reassemble/CB_IMGPSScanImp.api.pas
index 5215da9..1e95596 100644
--- a/reassemble/CB_IMGPSScanImp.api.pas
+++ b/reassemble/CB_IMGPSScanImp.api.pas
@@ -556,7 +556,7 @@
{ ==============================================================================
方法名稱:GetOMRCheckSet
- 引用相依:FileExists, LoadFromFile, SaveToFile, dnFile_Get, dnFile
+ 引用相依:FileExists, LoadFromFile, SaveToFile, dnFile, dnFile_Get
方法描述:從伺服器下載並更新 OMR 檢核設定檔(OMRSet.zip)。程序會檢查本地 LastDat
eTime.dat 取得最後更新時間,並發送請求。若伺服器有新資料,則下載後解壓
縮並更新本地時間戳記;若無更新則維持現狀,並包含完整的錯誤處理邏輯。
@@ -623,7 +623,7 @@
{ ==============================================================================
方法名稱:GetKeyinSet
- 引用相依:FileExists, LoadFromFile, SaveToFile, dnFile_Get, dnFile
+ 引用相依:FileExists, LoadFromFile, SaveToFile, dnFile, dnFile_Get
方法描述:從伺服器下載並更新登打設定檔(KeyinSet.zip)。運作機制與 GetOMRCheckSet
相同,透過比對時間戳記決定是否執行下載與解壓縮,確保本地的登打定位資
訊與伺服器同步。
@@ -748,7 +748,7 @@
{ ==============================================================================
方法名稱:CaseComplete
- 引用相依:FileExists, LoadFromFile, En_DecryptionStr_Base64
+ 引用相依:En_DecryptionStr_Base64, FileExists, LoadFromFile
方法描述:通知伺服器案件傳送完成。函式會收集案件的各項元數據,包含總頁數、主表單
ID、經辦資訊、被保人資料等,並根據不同的業務模式(如 NSCAN, ESCAN)格式化
發送數據。若包含 OMR 檢核失敗資訊或備註,也會一併封裝傳送,最後根據伺服
diff --git a/reassemble/CB_IMGPSScanImp.docmod.pas b/reassemble/CB_IMGPSScanImp.docmod.pas
index d484a01..c8172a8 100644
--- a/reassemble/CB_IMGPSScanImp.docmod.pas
+++ b/reassemble/CB_IMGPSScanImp.docmod.pas
@@ -79,7 +79,7 @@
{ ==============================================================================
方法名稱:ErrFormtoCurrentForm
- 引用相依:LoadFromFile, FileExists, RenameFile, SaveToFile, MoveFile
+ 引用相依:FileExists, LoadFromFile, MoveFile, RenameFile, SaveToFile
方法描述:修正案件中歸類錯誤的表單代碼及其關聯檔案。邏輯如下:
1. 取得錯誤與正確表單對應的文件編號。
2. 遍歷案件下的所有文件目錄,載入各目錄的影像索引檔 (Context.dat)。
diff --git a/reassemble/CB_IMGPSScanImp.fileOp.pas b/reassemble/CB_IMGPSScanImp.fileOp.pas
index c39b416..c2e2b64 100644
--- a/reassemble/CB_IMGPSScanImp.fileOp.pas
+++ b/reassemble/CB_IMGPSScanImp.fileOp.pas
@@ -64,7 +64,7 @@
{ ==============================================================================
方法名稱:DeleteFormCodeFile
- 引用相依:FileExists, LoadFromFile, DeleteImageFile, ReSortFileName, SaveToFil
+ 引用相依:DeleteImageFile, FileExists, LoadFromFile, ReSortFileName, SaveToFil
e
方法描述:刪除案件中指定 FormID 的所有文件。讀取 Context.dat 並遍歷,若 FormID
匹配則執行刪除(在 ESCAN 模式下會檢查是否非當次掃瞄以保護舊圖)。刪除後
@@ -128,8 +128,8 @@
{ ==============================================================================
方法名稱:DeleteDocNoFile
- 引用相依:DeleteDocNoFile, SaveToFile, ReSortFileName, LoadFromFile, FileExist
- s
+ 引用相依:DeleteDocNoFile, FileExists, LoadFromFile, ReSortFileName, SaveToFil
+ e
方法描述:刪除指定的文件編號(DocNo)影像。遍歷 ContextList,比對文件編號後執行實
體刪除與清單移除(含 Context 與 Context_DocNo)。處理完成後執行檔案重新
排序並重新載入清單。
@@ -163,7 +163,7 @@
{ ==============================================================================
方法名稱:DeleteDocNoFileForESCAN
- 引用相依:DeleteDocNoFile, SaveToFile, LoadFromFile, _DelTree
+ 引用相依:DeleteDocNoFile, LoadFromFile, SaveToFile, _DelTree
方法描述:在補件模式 (ESCAN) 下刪除屬於特定文件類型 (DocNo) 的影像。方法會從索
引清單 (ContextList) 的末尾開始向前遍歷,識別符合目標文件編號或附件名
稱的圖檔。若該檔案並非預先存在的(ISExistImg 返回 False),則執行實體刪
@@ -245,7 +245,7 @@
{ ==============================================================================
方法名稱:ReSortFileName
- 引用相依:ReSortFileName, FileExists, LoadFromFile, RenameFile, SaveToFile
+ 引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:執行影像檔案名稱的重新排序與更名。讀取目錄下的 Context.dat,根據目前的
排列順序為每個檔案產生新的三位數序號前綴,並呼叫 ReNameFile 執行磁碟
更名,最後同步更新清單內容並儲存。
@@ -281,7 +281,7 @@
{ ==============================================================================
方法名稱:ReSortFileName_New
- 引用相依:ReSortFileName, FileExists, LoadFromFile, RenameFile, SaveToFile
+ 引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:與 ReSortFileName 類似,執行影像檔案名稱的重新排序,但採用從清單末尾向
前遍歷的方式執行更名與儲存。
============================================================================== }
@@ -315,7 +315,7 @@
{ ==============================================================================
方法名稱:ReSortFileName2Scanlist
- 引用相依:ReSortFileName, FileExists, LoadFromFile, RenameFile, SaveToFile
+ 引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:針對 scanlist.dat 檔案內的影像路徑進行序號重排。讀取清單後,依序為檔案
名稱加上新的序號前綴並存回。
============================================================================== }
diff --git a/reassemble/CB_IMGPSScanImp.lfcycle.pas b/reassemble/CB_IMGPSScanImp.lfcycle.pas
index 30e973a..bcc1bab 100644
--- a/reassemble/CB_IMGPSScanImp.lfcycle.pas
+++ b/reassemble/CB_IMGPSScanImp.lfcycle.pas
@@ -311,7 +311,7 @@
{ ==============================================================================
方法名稱:Timer1Timer
- 引用相依:FJpgCompression, GetLocalAppDir, Str2Dir, _DelTree, FileExists, init
+ 引用相依:FJpgCompression, FileExists, GetLocalAppDir, Str2Dir, _DelTree, init
kscan
方法描述:OCX 元件初始化的核心程序。負責從伺服器下載各類基礎資訊(業務、表單、文件
、檢核規則、常用片語、系統參數等),並設定本地暫存路徑(ScanTemp)。針對異動
diff --git a/reassemble/CB_IMGPSScanImp.misc.pas b/reassemble/CB_IMGPSScanImp.misc.pas
index 6c79aa4..36bb7af 100644
--- a/reassemble/CB_IMGPSScanImp.misc.pas
+++ b/reassemble/CB_IMGPSScanImp.misc.pas
@@ -138,7 +138,7 @@
{ ==============================================================================
方法名稱:InitExistImgList
- 引用相依:LoadFromFile, LoadFileGetMD5
+ 引用相依:LoadFileGetMD5, LoadFromFile
方法描述:初始化已存在的影像清單。讀取案件路徑下 Download\Context.dat 的檔案內
容,計算每個檔案的 MD5 雜湊值並存入 ExistImgList,同時將處理過程記錄至
日誌檔。
diff --git a/reassemble/CB_IMGPSScanImp.omr.pas b/reassemble/CB_IMGPSScanImp.omr.pas
index a4dd812..7a4fa79 100644
--- a/reassemble/CB_IMGPSScanImp.omr.pas
+++ b/reassemble/CB_IMGPSScanImp.omr.pas
@@ -1,4 +1,72 @@
{ ==============================================================================
+ 方法名稱:GetSiteOMR
+ 引用相依:FindPoint, GetSiteOMR, Get_OMR, LoadFromFile
+ 方法描述:在指定影像文件的特定座標執行 OMR (光學標記辨識)。核心邏輯包含:
+ 1. 檢查並載入影像檔(若尚未載入),並呼叫 ClearLine 初始化黑白緩衝區。
+ 2. 讀取影像的 DPI 與寬高資訊。
+ 3. 使用 CM_Str2Rect 將 Site 字串轉為 TRect 矩陣,並參考定位點 (UpLPoi
+ nt) 進行位移計算。
+ 4. 限制辨識區域座標不超出影像邊界。
+ 5. 呼叫 Get_OMR 對黑白圖形緩衝區執行辨識並返回結果值(通常為 1 或 0)。
+ 此方法是自動化資料檢核的重要工具。
+============================================================================== }
+function TCB_IMGPSScanX.GetSiteOMR(FileName,Site:String;bt: Integer): Integer;
+var
+ OMRRect : TRect;
+ Xdpi,Ydpi : Integer;
+ W,H : Integer;
+begin
+ Result := 0;
+//ShowMessage('GetSiteOMR');
+
+ IF (ImageScrollBox1.FileName <> FileName) and (FileName <> '') then
+ begin
+//ShowMessage('11111'+ImageScrollBox1.FileName+#10#13+FileName);
+ ImageScrollBox1.LoadFromFile(FileName,1);
+{
+ShowMessage('UpLPoint='+IntToStr(UpLPoint.X)+','+IntToStr(UpLPoint.Y)+#10#13+
+'UpRPoint='+IntToStr(UpRPoint.X)+','+IntToStr(UpRPoint.Y)+#10#13+
+'DownLPoint='+IntToStr(DownLPoint.X)+','+IntToStr(DownLPoint.Y)+#10#13+
+'DownRPoint='+IntToStr(DownRPoint.X)+','+IntToStr(DownRPoint.Y));
+ FindPoint(ImageScrollBox1.Graphic,UpLPoint,UpRPoint,DownLPoint,'');
+ShowMessage('UpLPoint='+IntToStr(UpLPoint.X)+','+IntToStr(UpLPoint.Y)+#10#13+
+'UpRPoint='+IntToStr(UpRPoint.X)+','+IntToStr(UpRPoint.Y)+#10#13+
+'DownLPoint='+IntToStr(DownLPoint.X)+','+IntToStr(DownLPoint.Y)+#10#13+
+'DownRPoint='+IntToStr(DownRPoint.X)+','+IntToStr(DownRPoint.Y));
+}
+ ClearLine(ISB_BW.Graphic,bt);
+ ISB_BW.Redraw(True);
+ Application.ProcessMessages;
+ end;
+ If ImageScrollBox1.FileName <> '' Then
+ begin
+
+//ShowMessage('22222'+ImageScrollBox1.FileName);
+ Xdpi := ImagescrollBox1.Graphic.XDotsPerInch;
+ Ydpi := ImagescrollBox1.Graphic.YDotsPerInch;
+ H := ImageScrollBox1.Graphic.Height;
+ W := ImageScrollBox1.Graphic.Width;
+//ShowMessage('Xdpi='+IntToStr(Xdpi)+#10#13+'Ydpi='+IntToStr(Ydpi)+#10#13+'H='+IntToStr(H)+#10#13+'W='+IntToStr(W)+#10#13);
+//ShowMessage('Site='+Site);
+ OMRRect := CM_Str2Rect(Site,Xdpi,UpLPoint);
+Display1.Lines.Add('UpLPoint=('+IntToStr(UpLPoint.X)+','+IntToStr(UpLPoint.Y)+');'+Site+';'+IntToStr(OMRRect.Left)+','+IntToStr(OMRRect.top)+','+IntToStr(OMRRect.Right)+','+IntToStr(OMRRect.Bottom));
+ if OMRRect.Left < 0 then
+ OMRRect.Left := 0;
+ if OMRRect.Top < 0 then
+ OMRRect.Top := 0;
+ if OMRRect.Right > ImageScrollBox1.Graphic.Width then
+ OMRRect.Right := ImageScrollBox1.Graphic.Width;
+ if OMRRect.Bottom > ImageScrollBox1.Graphic.Height then
+ OMRRect.Bottom := ImageScrollBox1.Graphic.Height;
+
+ result := Get_OMR(ISB_BW.Graphic,OMRRect);
+//ShowMessage('result='+IntToStr(result));
+
+ end;
+end;
+
+
+{ ==============================================================================
方法名稱:CheckRule2OMRErrInfo
引用相依:
方法描述:將檢核規則清單(CHECK_RULE_INF_List)中的資料轉換為內部的 OMRErrInfo R
@@ -36,7 +104,7 @@
{ ==============================================================================
方法名稱:DistinctFormCode
- 引用相依:LoadFromFile, LoadFileGetMD5
+ 引用相依:LoadFileGetMD5, LoadFromFile
方法描述:從案件的 Context.dat 檔案中提取不重複的表單代碼(FormCode)並存入 OMRF
ileList。程序會遍歷上傳目錄下的所有檔案,檢查檔案是否存在且未被處理過。
接著比對 OMRFileList 中已有的表單代碼,若為新出現的表單代碼且檔案有效
@@ -91,8 +159,8 @@
{ ==============================================================================
方法名稱:OMRCheckCase
- 引用相依:ImageReSize_FormID, GetSiteOMR, FindPoint, LoadFromFile, FileExists,
- SaveToFile
+ 引用相依:FileExists, FindPoint, GetSiteOMR, ImageReSize_FormID, ImageResize,
+ LoadFromFile, SaveToFile
方法描述:執行案件的自動化 OMR 規則檢核,這是確保掃瞄案件合規性的核心邏輯。程序
流程:
1. 初始化檢核日誌。
diff --git a/reassemble/CB_IMGPSScanImp.prUpload.pas b/reassemble/CB_IMGPSScanImp.prUpload.pas
index 0715269..a53a342 100644
--- a/reassemble/CB_IMGPSScanImp.prUpload.pas
+++ b/reassemble/CB_IMGPSScanImp.prUpload.pas
@@ -53,8 +53,8 @@
{ ==============================================================================
方法名稱:Case2upload
- 引用相依:DirectoryExists, _DelTree, Str2Dir, CopyFile, FileExists, LoadFromFi
- le, SaveToFile
+ 引用相依:CopyFile, DirectoryExists, FileExists, LoadFromFile, SaveToFile, Str
+ 2Dir, _DelTree
方法描述:準備案件上傳用的資料夾結構。將分散在各文件子目錄下的影像檔案複製到單
一的 Upload 目錄下並重新編號檔名,同時產生彙整後的索引檔與附件。
============================================================================== }
@@ -187,7 +187,7 @@
{ ==============================================================================
方法名稱:Download2Case
- 引用相依:FileExists, CopyFile, LoadFromFile, DirectoryExists, SaveToFile
+ 引用相依:CopyFile, DirectoryExists, FileExists, LoadFromFile, SaveToFile
方法描述:將下載或匯入的案件結構還原回本系統的多層級目錄結構。包含建立文件子目
錄、檔案複製並重新編號、以及重建各類索引與份數設定檔。
============================================================================== }
diff --git a/reassemble/bloc/mermaid/BarCode2CaseID.md b/reassemble/bloc/mermaid/BarCode2CaseID.md
index 47a3b0c..865e52f 100644
--- a/reassemble/bloc/mermaid/BarCode2CaseID.md
+++ b/reassemble/bloc/mermaid/BarCode2CaseID.md
@@ -1,13 +1,15 @@
```mermaid
-graph TD
- Start([開始 BarCode2CaseID]) --> Init[Result = 空字串]
- Init --> LoopStart{遍歷 MpsBarcodeinf.Count}
- LoopStart -- i=1 to Count --> CheckLen{長度 == CaseIDLength?}
+flowchart TD
+ Start([開始 BarCode2CaseID]) --> InitResult[初始化 Result 為空字串]
+ InitResult --> LoopStart[遍歷條碼清單 i = 1 to Count]
- CheckLen -- 是 --> Found[Result = 條碼內容<br/>Break 迴圈]
- CheckLen -- 否 --> LoopNext[下一個條碼]
- LoopNext --> LoopStart
+ LoopStart --> CheckLen{條碼長度是否等於 CaseIDLength?}
+ CheckLen -- 是 --> SetResult[設定 Result 為此條碼]
+ CheckLen -- 否 --> NextIter[下一筆]
- Found --> End([結束])
- LoopStart -- 結束 --> End
+ SetResult --> BreakLoop[中斷迴圈]
+ NextIter --> LoopStart
+
+ BreakLoop --> End([結束])
+ LoopStart -- 遍歷完成 --> End
```
diff --git a/reassemble/bloc/mermaid/BarCode2FormID.md b/reassemble/bloc/mermaid/BarCode2FormID.md
index e0f9e60..722995e 100644
--- a/reassemble/bloc/mermaid/BarCode2FormID.md
+++ b/reassemble/bloc/mermaid/BarCode2FormID.md
@@ -1,19 +1,24 @@
```mermaid
-graph TD
- Start([開始 BarCode2FormID]) --> Init[Result = 空字串]
- Init --> LoopStart{遍歷 MpsBarcodeinf.Count}
- LoopStart -- i=1 to Count --> CheckLen{長度 == FormIDLength?}
+flowchart TD
+ Start([開始 BarCode2FormID]) --> InitResult[初始化 Result 為空字串]
+ InitResult --> LoopStart[遍歷條碼清單 i = 1 to Count]
- CheckLen -- 是 --> CheckAppear{FormIDAppear 驗證?}
- CheckLen -- 否 --> LoopNext[下一個條碼]
+ LoopStart --> CheckLen{條碼長度是否等於 FormIDLength?}
+ CheckLen -- 是 --> SetFormID[設定 FormID 為此條碼]
+ CheckLen -- 否 --> NextIter[下一筆]
- CheckAppear -- 通過 --> CheckExist{FormIDExists 驗證?}
- CheckAppear -- 不通過 --> ClearForm[FormID = 空] --> LoopNext
+ SetFormID --> VerifyAppear{FormIDAppear 驗證?}
+ VerifyAppear -- 失敗 --> ClearFormID[清空 FormID]
+ VerifyAppear -- 成功 --> CheckExists{FormIDExists 驗證?}
- CheckExist -- 通過 --> Found[Result = FormID<br/>Break 迴圈]
- CheckExist -- 不通過 --> LoopNext[下一個條碼]
+ ClearFormID --> CheckExists
- LoopNext --> LoopStart
- Found --> End([結束])
- LoopStart -- 結束 --> End
+ CheckExists -- 有效且 FormID 不為空 --> SetResult[設定 Result 為 FormID]
+ CheckExists -- 無效 --> NextIter
+
+ SetResult --> BreakLoop[中斷迴圈]
+ NextIter --> LoopStart
+
+ BreakLoop --> End([結束])
+ LoopStart -- 遍歷完成 --> End
```
diff --git a/reassemble/bloc/mermaid/GetUseCase.md b/reassemble/bloc/mermaid/GetUseCase.md
index be4e5c3..6f740fc 100644
--- a/reassemble/bloc/mermaid/GetUseCase.md
+++ b/reassemble/bloc/mermaid/GetUseCase.md
@@ -1,12 +1,13 @@
```mermaid
-graph TD
- Start([開始 GetUseCase]) --> InitIni[建立 TIniFile: Path + 'UseCase.ini']
- InitIni --> ModeCheck{檢查 Mode}
+flowchart TD
+ Start([開始 GetUseCase]) --> CreateIni[建立 UseCase.ini]
+ CreateIni --> CheckMode{判斷 Mode}
- ModeCheck -- 'F' (From) --> ReadFrom[讀取 FROM_CASEID]
- ModeCheck -- 'T' (To) --> ReadTo[讀取 TO_CASEID]
+ CheckMode -- 'F' (來源) --> ReadFrom[讀取 FROM_CASEID]
+ CheckMode -- 'T' (目標) --> ReadTo[讀取 TO_CASEID]
- ReadFrom --> Finally[釋放 TIniFile]
- ReadTo --> Finally
- Finally --> End([返回 Result])
+ ReadFrom --> Finalize[釋放 ini 物件]
+ ReadTo --> Finalize
+
+ Finalize --> End([返回結果並結束])
```
diff --git a/reassemble/bloc/mermaid/SetUseCase.md b/reassemble/bloc/mermaid/SetUseCase.md
index e7ee9cd..e8634e1 100644
--- a/reassemble/bloc/mermaid/SetUseCase.md
+++ b/reassemble/bloc/mermaid/SetUseCase.md
@@ -1,12 +1,13 @@
```mermaid
-graph TD
- Start([開始 SetUseCase]) --> InitIni[建立 TIniFile: Path + 'UseCase.ini']
- InitIni --> ModeCheck{檢查 Mode}
+flowchart TD
+ Start([開始 SetUseCase]) --> CreateIni[建立 UseCase.ini]
+ CreateIni --> CheckMode{判斷 Mode}
- ModeCheck -- 'A' (Add) --> AddAction[寫入 DocDir 區段:<br/>FROM_CASEID = FormCaseID<br/>TO_CASEID = ToCaseID]
- ModeCheck -- 'D' (Delete) --> DelAction[刪除 DocDir 區段]
+ CheckMode -- 'A' (新增) --> AddEntry[寫入 FROM_CASEID 與 TO_CASEID 到 DocDir 區段]
+ CheckMode -- 'D' (刪除) --> DelEntry[刪除 DocDir 區段]
- AddAction --> Finally[釋放 TIniFile]
- DelAction --> Finally
- Finally --> End([結束])
+ AddEntry --> Finalize[釋放 ini 物件]
+ DelEntry --> Finalize
+
+ Finalize --> End([結束])
```
diff --git a/reassemble/img/mermaid/CheckNeedCrop.md b/reassemble/img/mermaid/CheckNeedCrop.md
index fe8a6b7..f0c0d73 100644
--- a/reassemble/img/mermaid/CheckNeedCrop.md
+++ b/reassemble/img/mermaid/CheckNeedCrop.md
@@ -1,22 +1,16 @@
```mermaid
flowchart TD
- Start([開始 CheckNeedCrop]) --> Init[Result = False, FormIDCount = 0]
- Init --> CheckWidth{影像寬度 > 4 * XDPI?}
+ Start([開始]) --> GetFormInfo[查詢 FORM_INF_List 取得表單尺寸與定位模式]
+ GetFormInfo --> CheckType{是否為 ANCHOR 或 FRAME?}
- CheckWidth -- 是 --> LoopStart[遍歷條碼清單 MpsBarcodeinf]
- CheckWidth -- 否 --> FinalCheck
+ CheckType -- 是 --> LoadTmp[載入暫存影像檔]
+ CheckType -- 否 --> End([結束])
- LoopStart --> CheckBarcode{長度正確且表單代碼存在?}
- CheckBarcode -- 是 --> IncCount[FormIDCount + 1]
- CheckBarcode -- 否 --> NextItem
- IncCount --> NextItem{是否還有下一個?}
+ LoadTmp --> CheckResize[呼叫 CheckSize 檢查偏移與比例]
+ CheckResize --> NeedSave{是否需要儲存調整?}
- NextItem -- 是 --> LoopStart
- NextItem -- 否 --> FinalCheck
+ NeedSave -- 是 (SizeStr 非空) --> SaveTmp[將調整後的影像覆蓋存回]
+ NeedSave -- 否 --> ClearISB[清空顯示路徑]
- FinalCheck{FormIDCount 等於 2?}
- FinalCheck -- 是 --> SetTrue[Result = True]
- FinalCheck -- 否 --> End([結束])
-
- SetTrue --> End
+ SaveTmp --> ClearISB --> End
```
diff --git a/reassemble/img/mermaid/GetSiteOMR.md b/reassemble/img/mermaid/GetSiteOMR.md
index 125b0a1..03702f9 100644
--- a/reassemble/img/mermaid/GetSiteOMR.md
+++ b/reassemble/img/mermaid/GetSiteOMR.md
@@ -1,39 +1,12 @@
```mermaid
flowchart TD
- Start([開始 GetSiteOMR]) --> Init[Result = 0]
- Init --> CheckLoad{影像檔名不符且非空?}
+ Start([開始]) --> CheckFile{影像是否已載入?}
+ CheckFile -- 否 --> LoadImg[從檔案載入影像並清除緩衝線]
+ CheckFile -- 是 --> GetInfo[獲取影像 DPI 與寬高資訊]
- CheckLoad -- 是 --> LoadImg[載入影像 ImageScrollBox1.LoadFromFile]
- LoadImg --> ClearBW[初始化黑白緩衝區 ClearLine]
- ClearBW --> Redraw[重繪影像 ISB_BW.Redraw]
- Redraw --> ProcessMsg[處理系統訊息 Application.ProcessMessages]
- ProcessMsg --> CheckFileExist
-
- CheckLoad -- 否 --> CheckFileExist{ImageScrollBox1.FileName 非空?}
-
- CheckFileExist -- 是 --> GetInfo[獲取 DPI 與影像寬高]
- GetInfo --> ConvRect[轉換 Site 字串為 OMRRect 矩陣\nCM_Str2Rect]
- ConvRect --> LogDisp[記錄定位點與矩陣資訊到 Display1]
-
- LogDisp --> BoundaryL{Left < 0?}
- BoundaryL -- 是 --> SetL[Left = 0]
- BoundaryL -- 否 --> BoundaryT{Top < 0?}
- SetL --> BoundaryT
-
- BoundaryT -- 是 --> SetT[Top = 0]
- BoundaryT -- 否 --> BoundaryR{Right > Width?}
- SetT --> BoundaryR
-
- BoundaryR -- 是 --> SetR[Right = Width]
- BoundaryR -- 否 --> BoundaryB{Bottom > Height?}
- SetR --> BoundaryB
-
- BoundaryB -- 是 --> SetB[Bottom = Height]
- BoundaryB -- 否 --> CallOMR
- SetB --> CallOMR
-
- CallOMR[呼叫 Get_OMR 執行辨識] --> SetResult[Result = 辨識結果]
- SetResult --> End([結束])
-
- CheckFileExist -- 否 --> End
+ LoadImg --> GetInfo
+ GetInfo --> CalcRect[將 Site 字串轉為座標矩陣, 並參考定位點位移]
+ CalcRect --> BoundCheck[限制座標不超出影像邊界]
+ BoundCheck --> GetOMR[呼叫 Get_OMR 執行辨識]
+ GetOMR --> ReturnResult[返回辨識結果] --> End([結束])
```
diff --git a/reassemble/img/mermaid/ImageReSize_FormID.md b/reassemble/img/mermaid/ImageReSize_FormID.md
index d4bca0e..3b036a9 100644
--- a/reassemble/img/mermaid/ImageReSize_FormID.md
+++ b/reassemble/img/mermaid/ImageReSize_FormID.md
@@ -1,36 +1,19 @@
```mermaid
flowchart TD
- Start([開始 ImageReSize_FormID]) --> GetFormID[獲取 FormID]
- GetFormID --> CheckID{FormID 為空?}
- CheckID -- 是 --> End([結束])
- CheckID -- 否 --> QueryDB[查詢資料庫獲取表單高寬與定位類型]
+ Start([開始]) --> GetFormInfo[查詢 FORM_INF_List 取得高寬與定位類型]
+ GetFormInfo --> ValidParam{是否有定位點設定?}
- QueryDB --> Found{找到資料?}
- Found -- 否 --> End
- Found -- 是 --> CheckType{定位類型為 ANCHOR/FRAME\n且高寬資訊完整?}
+ ValidParam -- 是 --> LoadImg[載入影像檔 (補件模式則跳過)]
+ ValidParam -- 否 --> End([結束])
- CheckType -- 否 --> End
- CheckType -- 是 --> LoadImg[載入影像檔]
+ LoadImg --> FindAnchor[呼叫 FindPoint 尋找十字線或邊框定位點]
+ FindAnchor --> CalcResize[呼叫 CheckSize 計算偏移與縮放比例]
+ CalcResize --> PerformResize[呼叫 ImageResize 執行影像調整]
- LoadImg --> CheckSub{補件模式且圖檔已存在?}
- CheckSub -- 是 --> End
- CheckSub -- 否 --> FindPt1[執行定位點尋找 FindPoint]
+ PerformResize --> ResizeOk{縮放是否成功?}
+ ResizeOk -- 是 --> SaveImg[儲存影像, 記錄 MD5 與 ReSize.dat 日誌]
+ ResizeOk -- 否 (Error) --> LogErr[將錯誤資訊寫入 AnchorError.dat]
- FindPt1 --> CalcSize[計算偏移與縮放比例 CheckSize]
- CalcSize --> Resize[執行影像縮放 ImageResize]
- Resize --> FindPt2[縮放後重新定位 FindPoint]
-
- FindPt2 --> CheckSuccess{SizeStr 有效且非 ERROR?}
-
- CheckSuccess -- 是 --> CheckMD5{檢查 MD5 是否重複}
- CheckMD5 --> SaveImg[儲存縮放後影像]
- SaveImg --> LogResize[記錄縮放資訊到 ReSize.dat]
- LogResize --> ClearName
-
- CheckSuccess -- 否 --> CheckError{SizeStr 為 ERROR?}
- CheckError -- 是 --> LogError[記錄錯誤到 AnchorError.dat]
- LogError --> ClearName
- CheckError -- 否 --> ClearName
-
- ClearName[清除 FileName 快取] --> End
+ SaveImg --> ClearISB[清空顯示路徑] --> End
+ LogErr --> ClearISB
```
diff --git a/reassemble/img/transformer.pas b/reassemble/img/transformer.pas
index bab1317..f967aa4 100644
--- a/reassemble/img/transformer.pas
+++ b/reassemble/img/transformer.pas
@@ -1,7 +1,7 @@
{ ==============================================================================
方法名稱:ImageReSize_FormID
- 引用相依:ImageReSize_FormID, FindPoint, CheckSize, LoadFromFile, SaveToFile,
- FileExists, LoadFileGetMD5
+ 引用相依:CheckSize, FileExists, FindPoint, ImageReSize_FormID, ImageResize, L
+ oadFileGetMD5, LoadFromFile, SaveToFile
方法描述:根據表單的十字定位點或邊框 (ANCHOR/FRAME) 對掃瞄影像進行縮放調整。流
程如下:
1. 從 FORM_INF_List 取得表單預設高寬與定位類型。
@@ -93,7 +93,7 @@
{ ==============================================================================
方法名稱:ImageReSize_tmp
- 引用相依:ImageReSize_tmp, CheckSize, LoadFromFile, SaveToFile
+ 引用相依:CheckSize, ImageReSize_tmp, ImageResize, LoadFromFile, SaveToFile
方法描述:針對暫存影像檔案執行十字定位點縮放處理。此方法是 ImageReSize_FormID
的簡化版本,主要針對暫存檔 (FileName) 與指定的 FormID。邏輯包含從資料
庫清單查詢表單尺寸與定位模式,若符合 ANCHOR 或 FRAME 類型,則載入影像
@@ -129,7 +129,7 @@
{ ==============================================================================
方法名稱:CheckNeedCrop
- 引用相依:TDibGraphic, CheckNeedCrop
+ 引用相依:CheckNeedCrop, TDibGraphic
方法描述:判斷掃瞄影像是否為 A3 尺寸並需要進行切割(Crop)。判定邏輯有二:首先,檢
查影像寬度是否大於 4 倍的 DPI 閥值,藉此初步判斷為大尺寸掃瞄件;其次,
遍歷目前的條碼清單 (MpsBarcodeinf),統計有效的表單代碼 (FormID) 數量。
diff --git a/reassemble/mermaid/lfcycle/DestroyEvent.md b/reassemble/mermaid/lfcycle/DestroyEvent.md
new file mode 100644
index 0000000..322582b
--- /dev/null
+++ b/reassemble/mermaid/lfcycle/DestroyEvent.md
@@ -0,0 +1,13 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> FreeLists[逐一釋放所有 TStringList 物件資源]
+ FreeLists --> SpecialMode{是否為 DSCAN 或 ESCAN?}
+
+ SpecialMode -- 是 --> CheckPath{ImagePath 是否非空?}
+ CheckPath -- 是 --> DelTree[執行 _DelTree 刪除暫存影像目錄]
+ CheckPath -- 否 --> TriggerEvent
+
+ SpecialMode -- 否 --> TriggerEvent[觸發 COM 介面的 OnDestroy 事件]
+ DelTree --> TriggerEvent
+ TriggerEvent --> End([結束])
+```
diff --git a/reassemble/mermaid/lfcycle/InitialLanguage.md b/reassemble/mermaid/lfcycle/InitialLanguage.md
new file mode 100644
index 0000000..9029c04
--- /dev/null
+++ b/reassemble/mermaid/lfcycle/InitialLanguage.md
@@ -0,0 +1,23 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> LoadIni[讀取 Language.Lng 設定檔]
+ LoadIni --> SetGlobal[設定 IISUnit 的語言路徑與語系變數]
+ SetGlobal --> LoopComps[遍歷畫面上所有控制項]
+
+ LoopComps --> MatchType{判斷控制項類型}
+ MatchType -- Button/Label/GroupBox --> SetCaption[從 INI 讀取對應 Caption 並設定]
+ MatchType -- BitBtn/PJMenuBtn --> SetHint[從 INI 讀取對應 Hint 並設定]
+ MatchType -- MenuItem --> SetMenuCaption[設定選單項目文字]
+ MatchType -- ListView --> SetColCaption[遍歷設定欄位標題]
+ MatchType -- RadioGroup --> SetItems[設定標題與選項清單文字]
+
+ SetCaption --> NextComp[處理下一個控制項]
+ SetHint --> NextComp
+ SetMenuCaption --> NextComp
+ SetColCaption --> NextComp
+ SetItems --> NextComp
+
+ NextComp --> LoopEnd{所有控制項處理完畢?}
+ LoopEnd -- 否 --> LoopComps
+ LoopEnd -- 是 --> FreeIni[釋放資源] --> End([結束])
+```
diff --git a/reassemble/mermaid/lfcycle/Timer1Timer.md b/reassemble/mermaid/lfcycle/Timer1Timer.md
new file mode 100644
index 0000000..33e1db1
--- /dev/null
+++ b/reassemble/mermaid/lfcycle/Timer1Timer.md
@@ -0,0 +1,20 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> InitVars[初始化變數並設定為 False]
+ InitVars --> UIConfig[根據 FMode 隱藏/顯示功能按鈕與面板]
+ UIConfig --> CallI18n[呼叫 InitialLanguage 載入語系]
+
+ CallI18n --> DataLoading[顯示資料載入中提示]
+ DataLoading --> FetchServer[獲取主機時間與範本資訊]
+ FetchServer --> FetchInf[分次請求 DOC_INF, FORM_INF, 規則等系統資訊]
+
+ FetchInf --> PathConfig[設定本機暫存路徑與檢核路徑]
+ PathConfig --> SpecialMode{是否為 RSCAN/ESCAN?}
+
+ SpecialMode -- 是 --> DownloadCase[下載既有影像並處理舊案轉檔]
+ SpecialMode -- 否 --> LoadLocal[載入本地影像檔案]
+
+ DownloadCase --> LoadLocal
+ LoadLocal --> SetOk[設定 InitialOk = True 並停止載入提示]
+ SetOk --> LogEnd[記錄初始化結束日誌] --> End([結束])
+```
diff --git a/reassemble/mermaid/omr/CheckRule2OMRErrInfo.md b/reassemble/mermaid/omr/CheckRule2OMRErrInfo.md
index d7f1036..a9a3d63 100644
--- a/reassemble/mermaid/omr/CheckRule2OMRErrInfo.md
+++ b/reassemble/mermaid/omr/CheckRule2OMRErrInfo.md
@@ -1,24 +1,26 @@
```mermaid
-graph TD
- Start([開始 CheckRule2OMRErrInfo]) --> LoopStart{遍歷 i = 1 to 11}
- LoopStart -- I --> FindData[FindSQLData 查詢 CHECK_RULE_INF_List]
+flowchart TD
+ Start([開始 CheckRule2OMRErrInfo]) --> LoopStart[遍歷檢核規則 i = 1 to 11]
- FindData -- 找到資料 --> SetDisplay{MESG_SHOW_TYPE?}
- SetDisplay -- '1' --> DispTrue[OMRErrInfo.Display = True]
- SetDisplay -- '2' --> DispFalse[OMRErrInfo.Display = False]
+ LoopStart --> FormNo[產生三位數字編號 CheckNo]
+ FormNo --> SearchSQL{在 CHECK_RULE_INF_List 中搜尋?}
- DispTrue --> SetIgnore{MESG_DISP_TYPE?}
+ SearchSQL -- 找到 --> SetDisplay{判斷顯示類型?}
+ SetDisplay -- '1' --> DispTrue[Display = True]
+ SetDisplay -- '2' --> DispFalse[Display = False]
+
+ DispTrue --> SetIgnore{判斷忽略類型?}
DispFalse --> SetIgnore
- SetIgnore -- '1' --> IgnTrue[OMRErrInfo.Ignore = True]
- SetIgnore -- '2' --> IgnFalse[OMRErrInfo.Ignore = False]
+ SetIgnore -- '1' --> IgnTrue[Ignore = True]
+ SetIgnore -- '2' --> IgnFalse[Ignore = False]
- IgnTrue --> SetOther[設定 Info = CHECK_MESG<br/>設定 Mode = SCAN_MODE]
- IgnFalse --> SetOther
+ IgnTrue --> SetMeta[設定 Info 與 Mode]
+ IgnFalse --> SetMeta
- SetOther --> LoopNext[下一個 i]
- FindData -- 沒找到 --> LoopNext
+ SetMeta --> NextIter[下一個迴圈]
+ SearchSQL -- 找不到 --> NextIter
- LoopNext --> LoopStart
+ NextIter --> LoopStart
LoopStart -- 結束 --> End([結束])
```
diff --git a/reassemble/mermaid/omr/DistinctFormCode.md b/reassemble/mermaid/omr/DistinctFormCode.md
index 3181d4c..4be583b 100644
--- a/reassemble/mermaid/omr/DistinctFormCode.md
+++ b/reassemble/mermaid/omr/DistinctFormCode.md
@@ -1,26 +1,22 @@
```mermaid
-graph TD
- Start([開始 DistinctFormCode]) --> LoadFile[讀取 Context.dat 到 TStringList]
- LoadFile --> LoopFile{遍歷檔案清單}
+flowchart TD
+ Start([開始 DistinctFormCode]) --> LoadContext[讀取 Context.dat 到字串清單 S]
+ LoadContext --> LoopStart[遍歷清單 i = 0 to Count-1]
- LoopFile -- i --> CheckExist{影像是否存在或已縮放?}
- CheckExist -- 是 --> Skip[Continue 下一個]
- CheckExist -- 否 --> GetForm[提取檔案的 FormCode]
+ LoopStart --> CheckCat{FWH_category 為 'N'?}
+ CheckCat -- 是 --> CheckExist{檔案是否存在或已在 Resize 清單?}
+ CheckExist -- 是 --> Continue[跳過此筆]
+ CheckExist -- 否 --> ProcessFile
+ CheckCat -- 否 --> ProcessFile
- GetForm --> LoopOMR{遍歷 OMRFileList}
- LoopOMR -- n --> CompareForm{FormCode 是否重複?}
- CompareForm -- 是 --> MarkRepeat[AddOk = False, Break]
- CompareForm -- 否 --> NextOMR[下一個 OMR 項目]
- NextOMR --> LoopOMR
+ Continue --> NextIter
+ ProcessFile[提取 FormCode] --> CheckDup{OMRFileList 中是否已存在?}
- MarkRepeat --> CheckAdd{AddOk?}
- NextOMR -- 結束 --> CheckAdd
+ CheckDup -- 否 --> AddToList[加入 OMRFileList]
+ CheckDup -- 是 --> NextIter
- CheckAdd -- True --> AddList[加入 OMRFileList]
- CheckAdd -- False --> NextFile[下一個檔案]
+ AddToList --> NextIter[下一筆檔案]
+ NextIter --> LoopStart
- AddList --> NextFile
- Skip --> NextFile
- NextFile --> LoopFile
- LoopFile -- 結束 --> End([結束])
+ LoopStart -- 結束 --> End([釋放 S 並結束])
```
diff --git a/reassemble/mermaid/omr/OMRCheckCase.md b/reassemble/mermaid/omr/OMRCheckCase.md
index c7fbe9c..a1a5830 100644
--- a/reassemble/mermaid/omr/OMRCheckCase.md
+++ b/reassemble/mermaid/omr/OMRCheckCase.md
@@ -1,31 +1,33 @@
```mermaid
-graph TD
- Start([開始 OMRCheckCase]) --> Init[刪除舊日誌/初始化變數]
- Init --> GetMainID[獲取 MainFormID]
+flowchart TD
+ Start([開始 OMRCheckCase]) --> Init[刪除暫存檔並初始化變數]
+ Init --> GetMainID[取得主文件 ID]
- GetMainID --> MainCheck{MainFormID 是否存在?}
- MainCheck -- 否 --> Phase2[進入檔案清單檢查]
- MainCheck -- 是 --> CheckDep[檢查主要文件頁數 / 相依文件 / 互斥文件]
+ GetMainID --> CaseMain{主文件 ID 是否存在?}
- CheckDep --> Phase2
- Phase2 --> LoopContext[遍歷 Context.dat 檢查停用文件]
+ CaseMain -- 是 --> CheckMajor[執行主要文件頁數檢核]
+ CheckMajor --> CheckDeps[執行相依與互斥文件檢核]
+ CheckDeps --> CheckDisabled
- LoopContext --> MaxPage[檢查各表單是否超過最大頁數]
- MaxPage --> LoopOMRFiles{遍歷 OMRFileList 進行欄位檢核}
+ CaseMain -- 否 --> CheckDisabled[檢查所有表單是否停用]
- LoopOMRFiles -- 每張影像 --> Resize[執行十字定位縮放 ImageReSize_FormID]
- Resize --> LoadXML[載入對應 XML 規則]
+ CheckDisabled --> MaxPage[檢查表單最大頁數限制]
+ MaxPage --> LoopFiles[遍歷 OMRFileList]
- LoadXML --> CheckField1[Type 1: 必填欄位檢核]
- CheckField1 --> CheckField3[Type 3: 關聯欄位檢核]
- CheckField3 --> CheckField8[Type 8: 互斥填寫檢核]
- CheckField8 --> CheckField4[Type 4: 欄位有值附文件檢核]
- CheckField4 --> CheckField5[Type 5: 欄位有值不附文件檢核]
- CheckField5 --> CheckField6[Type 6: 欄位有值寫備註檢核]
- CheckField6 --> SaveValue[Type 7: OMR 帶值處理]
+ LoopFiles --> Resize[影像十字定位點縮放]
+ Resize --> LoadRules[載入對應 XML 規則檔]
- SaveValue --> NextOMRFile[下一個影像]
- NextOMRFile --> LoopOMRFiles
+ LoadRules --> Rule1[必填欄位檢核 settype1]
+ Rule1 --> Rule3[相關欄位關聯檢核 settype3]
+ Rule3 --> Rule8[互斥欄位關聯檢核 settype8]
+ Rule8 --> Rule4[相依文件檢核 settype4]
+ Rule4 --> Rule5[互斥文件檢核 settype5]
+ Rule5 --> Rule6[備註檢核 settype6]
+ Rule6 --> Rule7[OMR 帶值處理 settype7]
- LoopOMRFiles -- 結束 --> Finish([返回 CaseOk 結果])
+ Rule7 --> NextFile[下一張影像]
+ NextFile --> LoopFiles
+
+ LoopFiles -- 遍歷結束 --> FinalResult[返回 CaseOk 結果]
+ FinalResult --> End([結束])
```
diff --git a/reassemble/mermaid/omr/OMRErr2ini.md b/reassemble/mermaid/omr/OMRErr2ini.md
index deaa7f3..2a80264 100644
--- a/reassemble/mermaid/omr/OMRErr2ini.md
+++ b/reassemble/mermaid/omr/OMRErr2ini.md
@@ -1,10 +1,16 @@
```mermaid
-graph TD
- Start([開始 OMRErr2ini]) --> CheckDisp{Display?}
+flowchart TD
+ Start([開始 OMRErr2ini]) --> CheckDisp{判斷 Display 旗標?}
- CheckDisp -- True --> IniWrite[開啟 Checkerr.ini<br/>讀取目前 Count 並累加<br/>寫入 Reason, Site, FileName 等詳細資訊]
- CheckDisp -- False --> DatWrite[開啟 CheckMemo.dat<br/>附加 Reason 錯誤訊息字串]
+ CheckDisp -- True (紀錄到 ini) --> OpenIni[開啟 Checkerr.ini]
+ OpenIni --> IncCount[取得並遞增 OMRCount]
+ IncCount --> WriteDetails[寫入 Reason, Ignore, FileName, Site 等詳細資訊]
+ WriteDetails --> CloseIni[關閉並釋放 ini]
- IniWrite --> End([結束])
- DatWrite --> End
+ CheckDisp -- False (紀錄到 dat) --> OpenDat[讀取 CheckMemo.dat]
+ OpenDat --> AddReason[附加 Reason 訊息]
+ AddReason --> SaveDat[儲存 CheckMemo.dat]
+
+ CloseIni --> End([結束])
+ SaveDat --> End
```
diff --git a/reassemble/mermaid/omr/OMRErrini2List.md b/reassemble/mermaid/omr/OMRErrini2List.md
index 29c2e84..669e3c0 100644
--- a/reassemble/mermaid/omr/OMRErrini2List.md
+++ b/reassemble/mermaid/omr/OMRErrini2List.md
@@ -1,17 +1,20 @@
```mermaid
-graph TD
- Start([開始 OMRErrini2List]) --> OpenIni[讀取 Checkerr.ini]
- OpenIni --> LoopErr{遍歷錯誤序號 i = 1 to Count}
+flowchart TD
+ Start([開始 OMRErrini2List]) --> OpenIni[開啟 Checkerr.ini]
+ OpenIni --> GetCount[讀取錯誤總數 Errcount]
- LoopErr -- i --> CheckDel{Del == False?}
- CheckDel -- 是 --> AddLV[將 Reason 與索引加入 ListView]
- CheckDel -- 否 --> NextErr[下一個]
+ GetCount --> LoopStart[遍歷錯誤 i = 1 to Errcount]
+ LoopStart --> CheckDel{是否已被移除 Del?}
- AddLV --> NextErr
- NextErr --> LoopErr
+ CheckDel -- 否 --> AddToLV[將 Reason 與索引加入 ListView]
+ CheckDel -- 是 --> NextIter[下一筆]
- LoopErr -- 結束 --> CheckCount{ListView 是否有資料?}
- CheckCount -- 有 --> DisableBt[停用立即上傳按鈕 ImmediateBt]
- CheckCount -- 無 --> End([結束])
- DisableBt --> End
+ AddToLV --> NextIter
+ NextIter --> LoopStart
+
+ LoopStart -- 結束 --> CheckCount{ListView 是否有資料?}
+ CheckCount -- 是 --> DisableUpload[停用上傳按鈕]
+ CheckCount -- 否 --> End
+
+ DisableUpload --> End([結束])
```
diff --git a/reassemble/mermaid/omr/OMRErrini2ListForLog.md b/reassemble/mermaid/omr/OMRErrini2ListForLog.md
index 7109cf6..13033d8 100644
--- a/reassemble/mermaid/omr/OMRErrini2ListForLog.md
+++ b/reassemble/mermaid/omr/OMRErrini2ListForLog.md
@@ -1,21 +1,25 @@
```mermaid
-graph TD
- Start([開始 OMRErrini2ListForLog]) --> LoadCases[載入 CaseList.dat]
- LoadCases --> LoopCases{遍歷每個案件}
+flowchart TD
+ Start([開始 OMRErrini2ListForLog]) --> Init[初始化字串清單 ST 與 CaseList]
+ Init --> LoadCases[從 CaseList.dat 載入所有案件]
- LoopCases -- CaseID --> OpenIni[讀取該案件的 Checkerr.ini]
- OpenIni --> LoopErr{遍歷 Count}
+ LoadCases --> LoopCases[遍歷案件 I = 0 to Count-1]
+ LoopCases --> OpenIni[開啟該案件的 Checkerr.ini]
+ OpenIni --> GetCount[讀取錯誤總數 Errcount]
- LoopErr -- j --> CheckDel{Del == False?}
- CheckDel -- 是 --> AddToST[將 Reason 加入字串清單]
- CheckDel -- 否 --> NextErr[下一個錯誤]
+ GetCount --> LoopErrors[遍歷錯誤 j = 1 to Errcount]
+ LoopErrors --> CheckDel{是否已被移除?}
- AddToST --> NextErr
- NextErr --> LoopErr
+ CheckDel -- 否 --> AddToST[將 Reason 加入 ST]
+ CheckDel -- 是 --> NextError[下一筆錯誤]
- LoopErr -- 結束 --> NextCase[下一個案件]
+ AddToST --> NextError
+ NextError --> LoopErrors
+
+ LoopErrors -- 結束 --> NextCase[下一筆案件]
NextCase --> LoopCases
- LoopCases -- 結束 --> Result[返回 ST.Text]
- Result --> End([結束])
+ LoopCases -- 結束 --> ReturnText[返回 ST.Text 完整錯誤內容]
+ ReturnText --> Cleanup[釋放清單物件]
+ Cleanup --> End([結束])
```
diff --git a/reassemble/scan/mermaid/GetDefScanIni.md b/reassemble/scan/mermaid/GetDefScanIni.md
index 645d639..8fbe186 100644
--- a/reassemble/scan/mermaid/GetDefScanIni.md
+++ b/reassemble/scan/mermaid/GetDefScanIni.md
@@ -1,23 +1,22 @@
```mermaid
-graph TD
- Start([Start GetDefScanIni]) --> SetHardDefaults[設定程式內建預設值<br/>Def_DeviceDelete=True, DPI=300 等]
- SetHardDefaults --> LoopList[遍歷 WORK_INF_List]
+flowchart TD
+ Start([開始]) --> SetHardDefaults[設定硬體預設值: DPI=300, 雙面=True, 旋轉=0 等]
+ SetHardDefaults --> LoopList[遍歷 WORK_INF_List 中的參數]
+ LoopList --> MatchParam{比對 PARA_NO}
- subgraph ParaMatching
- LoopList --> MatchPara{比對 PARA_NO}
- MatchPara -- SCAN_BLANKDEL --> UpdBlank[更新空白頁刪除設定]
- MatchPara -- SCAN_REVERSE --> UpdRev[更新影像反相設定]
- MatchPara -- SCAN_DPI --> UpdDpi[更新 DPI]
- MatchPara -- SCAN_DUPLEX --> UpdDup[更新雙面掃瞄]
- MatchPara -- SCAN_ROTATE --> UpdRot[更新旋轉角度]
- MatchPara -- SCAN_IMGSET --> UpdImgSet[更新亮度對比設定]
- MatchPara -- LOCAL_PATH --> UpdPath[更新 ImagePath]
- MatchPara -- GUIDE/DIV_ID --> UpdFormID[更新導引/分案頁代碼列表]
- MatchPara -- Others --> UpdMisc[更新壓縮比/上傳限制等]
- end
+ MatchParam -- 'SCAN_DPI' --> SetDPI[設定 DPI 數值]
+ MatchParam -- 'SCAN_DUPLEX' --> SetDuplex[設定是否雙面]
+ MatchParam -- 'SCAN_ROTATE_MODE' --> SetRotate[設定旋轉角度]
+ MatchParam -- 'LOCAL_PATH' --> SetPath[設定影像儲存路徑]
+ MatchParam -- 'GUIDEFORMID' --> SetGuide[設定導引頁代碼列表]
- UpdMisc --> LoopNext[下一個參數]
- LoopNext --> LoopList
- LoopList -- 結束 --> FinalSet[ScanDuplex := Def_ScanDuplex]
- FinalSet --> EndGetDef([End])
+ SetDPI --> NextItem[下一個參數]
+ SetDuplex --> NextItem
+ SetRotate --> NextItem
+ SetPath --> NextItem
+ SetGuide --> NextItem
+
+ NextItem --> LoopEnd{所有參數處理完畢?}
+ LoopEnd -- 否 --> LoopList
+ LoopEnd -- 是 --> End([結束])
```
diff --git a/reassemble/scan/mermaid/OnAcquire.md b/reassemble/scan/mermaid/OnAcquire.md
index 0b40162..5e8a361 100644
--- a/reassemble/scan/mermaid/OnAcquire.md
+++ b/reassemble/scan/mermaid/OnAcquire.md
@@ -1,39 +1,31 @@
```mermaid
-graph TD
- Start([Start OnAcquire]) --> GetInfo[取得 pScanInfo]
- GetInfo --> MultiPage{MultiPage?}
+flowchart TD
+ Start([開始]) --> GetInfo[獲取 CallBackData 並轉為 ScanInfo 指針]
+ GetInfo --> AssignDIB[將 DIB 句柄轉為影像對象並設定 DPI]
+ AssignDIB --> FormatCheck{檢查影像格式}
- subgraph ImagePreprocessing
- MultiPage -- Yes --> AssignDib[Assign DIB to Graphic & Set DPI]
- AssignDib --> CheckFormat{ImageFormat?}
- CheckFormat -- BlackWhite --> BWProc[條碼辨識/旋轉/反向/傾斜矯正/清黑邊]
- CheckFormat -- TrueColor --> ColorProc[條碼辨識/旋轉/設定 JPEG 壓縮]
- CheckFormat -- Gray/Color256 --> GrayProc[轉灰階/設定 JPEG 壓縮]
- CheckFormat -- Others --> OtherProc[設定 PackBits 壓縮]
- end
+ FormatCheck -- 黑白 (ifBlackWhite) --> BWProc[條碼辨識, 旋轉, 反向, 去偏斜, 清黑邊]
+ FormatCheck -- 全彩 (ifTrueColor) --> ColorProc[設定 JPEG 壓縮品質與條碼辨識旋轉]
+ FormatCheck -- 灰階 (ifGray256) --> GrayProc[設定 JPEG 壓縮品質與條碼辨識旋轉]
- subgraph CropAndSave
- ImagePreprocessing --> CreateTempGr[建立 iGraphic_First, iGraphic_sec]
- CreateTempGr --> CropCheck{需要裁切 A3?}
- CropCheck -- Yes --> DoCrop[將影像裁切為左右兩份]
- CropCheck -- No --> SetFirst[iGraphic := iGraphic_First]
-
- DoCrop --> SetFirst
- SetFirst --> WhileLoop{iGraphic 不為空?}
-
- WhileLoop -- Yes --> BlankCheck{是否刪除空白頁?}
- BlankCheck -- No/Valid --> PageProcess[UI 顯示影像<br/>PageEnd 決定路徑與檔名]
- PageProcess --> SaveFile{儲存檔案}
- SaveFile -- .tif --> AppendTif[Append To Stream]
- SaveFile -- .jpg --> SaveJpg[Save To File]
- AppendTif --> DoPageDone[PageDone]
- SaveJpg --> DoPageDone
-
- DoPageDone --> NextImg[切換至 iGraphic_Sec 或 設為空]
- BlankCheck -- IsBlank --> NextImg
- NextImg --> WhileLoop
- end
+ BWProc --> CropCheck{檢查是否需 A3 切割為 A4?}
+ ColorProc --> CropCheck
+ GrayProc --> CropCheck
- WhileLoop -- No --> FinallyFree[釋放暫存 Graphic 資源]
- FinallyFree --> EndOnAcquire([End])
+ CropCheck -- 是 --> PerformCrop[執行影像切割為第一與第二部分]
+ CropCheck -- 否 --> SingleImg[直接處理原始影像]
+
+ PerformCrop --> LoopPages[對每一部分進行迴圈處理]
+ SingleImg --> LoopPages
+
+ LoopPages --> BlankCheck{是否刪除空白頁?}
+ BlankCheck -- 否/非空白 --> SaveProc[呼叫 PageEnd 決定路徑檔名並儲存檔案]
+ BlankCheck -- 是空白 --> NextPage[處理下一部分]
+
+ SaveProc --> CallPageDone[呼叫 PageDone 更新 UI]
+ CallPageDone --> NextPage
+
+ NextPage --> LoopEnd{所有部分處理完畢?}
+ LoopEnd -- 否 --> LoopPages
+ LoopEnd -- 是 --> FreeRes[釋放資源] --> End([結束])
```
diff --git a/reassemble/scan/mermaid/PageDone.md b/reassemble/scan/mermaid/PageDone.md
index 2a78954..2ff68b6 100644
--- a/reassemble/scan/mermaid/PageDone.md
+++ b/reassemble/scan/mermaid/PageDone.md
@@ -1,21 +1,15 @@
```mermaid
-graph TD
- Start([Start PageDone]) --> IncCount[Scaninfo.ImageCount 遞增]
- IncCount --> CaseMode{ScanMode?}
+flowchart TD
+ Start([開始]) --> IncCount[累加掃描影像計數]
+ IncCount --> ModeCheck{檢查掃描模式}
- CaseMode -- smNew --> NewMode[根據 ScanImgShowMode 設定 ISB]
- NewMode --> ShowType{顯示模式?}
- ShowType -- 清楚/模糊 --> LoadNew[ISB.LoadFromFile<br/>PEFileName]
- ShowType -- 不顯示 --> smReplace
+ ModeCheck -- 新案 (smNew) --> NewMode[根據顯示模式尋找 ISB 並載入影像]
+ ModeCheck -- 取代 (smReplace) --> ReplaceMode[將影像載入當前顯示的 ISB]
+ ModeCheck -- 插入 (smInsert) --> InsertMode[尋找 ISB 並以符合頁面模式載入影像]
+ ModeCheck -- 範本 (smSample) --> SampleMode[尋找 ISB 並載入影像]
- CaseMode -- smReplace --> LoadRep[DisplayISB.LoadFromFile]
- CaseMode -- smInsert --> LoadIns[ISB.LoadFromFile]
- CaseMode -- smSample --> LoadSam[ISB.LoadFromFile]
- CaseMode -- smRTS --> EndPageDone
-
- LoadNew --> EndPageDone
- LoadRep --> EndPageDone
- LoadIns --> EndPageDone
- LoadSam --> EndPageDone
- EndPageDone([End])
+ NewMode --> End([結束])
+ ReplaceMode --> End
+ InsertMode --> End
+ SampleMode --> End
```
diff --git a/reassemble/scan/mermaid/PageEnd.md b/reassemble/scan/mermaid/PageEnd.md
index 359b438..723c567 100644
--- a/reassemble/scan/mermaid/PageEnd.md
+++ b/reassemble/scan/mermaid/PageEnd.md
@@ -1,38 +1,20 @@
```mermaid
-graph TD
- Start([Start PageEnd]) --> CaseMode{ScanMode?}
+flowchart TD
+ Start([開始]) --> ModeCheck{檢查掃描模式}
- subgraph smNew_Logic
- CaseMode -- smNew --> GetFormID[獲取 FormID / 導引頁 / 分案頁資訊]
- GetFormID --> IsDiv{偵測到分案條碼?}
- IsDiv -- Yes --> ResetCase[重置計數/清空 View/取得新 ScanCaseno]
- IsDiv -- No --> CheckCaseNo{ScanCaseno 為空?}
- CheckCaseNo -- Yes --> GetNoName[GetNoNameCase]
- CheckCaseNo -- No --> InitPath[建立目錄 Str2Dir]
-
- GetNoName --> InitPath
- InitPath --> DocDir[決定 ScanDocDir<br/>處理分份數邏輯]
- DocDir --> SetDocList[SetDocNoList 更新目錄索引]
- SetDocList --> GenFileName[產生 ScanSaveFilename 序號_FormID]
- GenFileName --> SaveCheck{不存檔條碼?}
- SaveCheck -- No --> SetContext[SetContextList<br/>更新 TreeView UI<br/>設定 PEFileName]
- end
+ ModeCheck -- 新案 (smNew) --> NewLogic[取得 FormID 與 DocNo, 處理分案/分份邏輯]
+ ModeCheck -- 插入 (smInsert) --> InsertLogic[取得 FormID 並判斷目標文件目錄]
+ ModeCheck -- 取代 (smReplace) --> ReplaceLogic[設定替換檔名與路徑]
+ ModeCheck -- 範本 (smSample) --> SampleLogic[設定範本儲存路徑]
- CaseMode -- smReplace --> DelOld[刪除舊檔] --> SetPE[設定 PEFileName]
+ NewLogic --> SubNew{是否偵測到分案頁?}
+ SubNew -- 是 --> ResetCase[重置計數並取得新案號, 更新 TreeView]
+ SubNew -- 否 --> CalcPath[計算儲存目錄與檔名, 更新 ContextList]
- subgraph smInsert_Logic
- CaseMode -- smInsert --> GetFormIDIns[獲取 FormID / DocNo]
- GetFormIDIns --> DocDirIns[尋找最後的 DocDir]
- DocDirIns --> GenFileNameIns[產生 ScanSaveFilename]
- GenFileNameIns --> SetContextIns[SetContextList<br/>設定 PEFileName]
- end
+ CalcPath --> SetFileName[設定 PEFileName]
+ InsertLogic --> SetFileName
+ ReplaceLogic --> SetFileName
+ SampleLogic --> SetFileName
- CaseMode -- smSample --> SamLogic[刪除舊檔/設定 PEFileName/顯示辨識條碼]
-
- SetContext --> EndPageEnd
- SetPE --> EndPageEnd
- SetContextIns --> EndPageEnd
- SamLogic --> EndPageEnd
-
- EndPageEnd([End])
+ SetFileName --> End([結束])
```
diff --git a/reassemble/scan/mermaid/R_W_Scanini.md b/reassemble/scan/mermaid/R_W_Scanini.md
index daa35ec..b7c6da9 100644
--- a/reassemble/scan/mermaid/R_W_Scanini.md
+++ b/reassemble/scan/mermaid/R_W_Scanini.md
@@ -1,15 +1,13 @@
```mermaid
-graph TD
- Start([Start R_W_Scanini]) --> CreateIni[建立 TIniFile: FBScan.ini]
- CreateIni --> TryBlock[try]
+flowchart TD
+ Start([開始]) --> CreateIni[建立 Tinifile 物件載入 FBScan.ini]
+ CreateIni --> ModeCheck{操作模式}
- subgraph ModeSwitch
- TryBlock --> ModeCheck{Mode?}
- ModeCheck -- 'R' (Read) --> ReadIni[從 Ini 讀取:<br/>DeviceDelete, Reverse, BoardClear, <br/>Rotate, Deskew, Brightness, Contrast 等]
- ModeCheck -- 'W' (Write) --> WriteIni[將變數寫入 Ini:<br/>DeviceDelete, Reverse, BoardClear, <br/>Rotate, Deskew, Brightness, Contrast 等]
- end
+ ModeCheck -- 'R' 讀取 --> ReadParams[讀取空白頁設定, 反向, 旋轉, 去偏斜, 亮度對比等]
+ ModeCheck -- 'W' 寫入 --> WriteParams[將當前參數值寫入設定檔]
- ModeSwitch --> FinallyBlock[finally]
- FinallyBlock --> FreeIni[釋放 Ini 物件]
- FreeIni --> EndRW([End])
+ ReadParams --> FreeIni[釋放 Tinifile 資源]
+ WriteParams --> FreeIni
+
+ FreeIni --> End([結束])
```
diff --git a/reassemble/scan/mermaid/StatrTwainScan.md b/reassemble/scan/mermaid/StatrTwainScan.md
index 9a2b72b..7b9be02 100644
--- a/reassemble/scan/mermaid/StatrTwainScan.md
+++ b/reassemble/scan/mermaid/StatrTwainScan.md
@@ -1,35 +1,13 @@
```mermaid
-graph TD
- Start([Start StatrTwainScan]) --> CheckConfig{Scanner.IsConfigured?}
- CheckConfig -- No --> MsgNoDriver[顯示 TWAIN 驅動尚未安裝訊息] --> ExitStatrTwainScan([Exit])
- CheckConfig -- Yes --> InitScanInfo[初始化 ScanInfo 結構<br/>建立 TTiffGraphic]
-
- InitScanInfo --> TryBlock1[try: 開始掃瞄設定]
-
- subgraph Try_Main
- TryBlock1 --> SetParams[設定 DPI, ScanColor, ShowUI]
- SetParams --> TryOpen[try: 開啟掃瞄來源]
-
- subgraph Try_OpenSource
- TryOpen --> OpenSource[Scanner.OpenSource]
- OpenSource --> SetDuplex[設定雙面/亮度/對比]
- end
-
- SetDuplex --> CatchOpen{發生錯誤?}
- CatchOpen -- Yes --> ShowErr[顯示掃瞄器錯誤]
- ShowErr --> CloseSrc1[Scanner.CloseSource] --> ExitStatrTwainScan
-
- CatchOpen -- No --> TryAcquire[try: 執行獲取影像]
-
- subgraph Try_Acquire
- TryAcquire --> Acquire[Scanner.AcquireWithSourceOpen<br/>傳入 OnAcquire 回呼]
- Acquire --> CatchAcq{發生 Exception?}
- CatchAcq -- Yes --> CloseSrc2[Scanner.CloseSource]
- end
-
- TryAcquire -. finally .-> CloseSrc3[Scanner.CloseSource]
- end
-
- Try_Main -. finally .-> FinalCleanup[Scanner.CloseSource<br/>ScanInfo.Graphic.Free]
- FinalCleanup --> EndStatrTwainScan([End])
+flowchart TD
+ Start([開始]) --> CheckConfig{掃描器驅動是否已安裝?}
+ CheckConfig -- 否 --> ShowErr[顯示錯誤訊息] --> End([結束])
+ CheckConfig -- 是 --> InitScanInfo[初始化 ScanInfo 並設定為多頁模式]
+ InitScanInfo --> SetScannerParams[設定掃描參數: DPI, 格式, UI 顯示模式]
+ SetScannerParams --> OpenSource[開啟掃描來源]
+ OpenSource --> TryAcquire[執行 AcquireWithSourceOpen 掃描作業]
+ TryAcquire --> CatchErr{掃描過程中發生錯誤?}
+ CatchErr -- 是 --> ShowScanErr[顯示掃描錯誤訊息] --> CloseSource1[關閉掃描來源] --> FreeRes[釋放 Graphic 資源] --> End
+ CatchErr -- 否 --> CloseSource2[掃描結束, 關閉掃描來源]
+ CloseSource2 --> FreeRes --> End
```
diff --git a/reassemble/scan/mermaid/initkscan.md b/reassemble/scan/mermaid/initkscan.md
index f0641de..4b34b61 100644
--- a/reassemble/scan/mermaid/initkscan.md
+++ b/reassemble/scan/mermaid/initkscan.md
@@ -1,21 +1,17 @@
```mermaid
-graph TD
- Start([Start initkscan]) --> DisableCB[ScanDuplexCB.Enabled := False]
- DisableCB --> CheckConfig{Scanner.IsConfigured?}
+flowchart TD
+ Start([開始]) --> DisableUI[將雙面掃描勾選框設為停用]
+ DisableUI --> CheckConfig{掃描器是否已設定?}
- CheckConfig -- Yes --> TryOpen[try]
+ CheckConfig -- 是 --> TryOpen[嘗試開啟掃描來源 (OpenSource)]
+ CheckConfig -- 否 --> End([結束])
- subgraph Try_Detect
- TryOpen --> OpenSrc[Scanner.OpenSource]
- OpenSrc --> CheckDuplex{Scanner.DuplexCap > 0?}
- CheckDuplex -- Yes --> EnableCB[ScanDuplexCB.Enabled := True]
- CheckDuplex -- No --> CatchErr
- EnableCB --> CatchErr{發生異常?}
- CatchErr -- Yes --> DataLoadErr[DataLoading False, True] --> ExitInit
- end
+ TryOpen --> CheckDuplex{硬體是否支援雙面?}
+ CheckDuplex -- 是 (DuplexCap > 0) --> EnableUI[啟用雙面掃描勾選框]
+ CheckDuplex -- 否 --> CloseSource[關閉掃描來源]
- Try_Detect --> CloseSrc[Scanner.CloseSource]
- CheckConfig -- No --> EndInit
- CloseSrc --> EndInit
- EndInit([End])
+ EnableUI --> CloseSource
+ CloseSource --> End
+
+ TryOpen -- 異常 --> StopLoading[呼叫 DataLoading 停止載入提示] --> End
```
diff --git a/reassemble/scan/twain.pas b/reassemble/scan/twain.pas
index 605cbd3..bdea582 100644
--- a/reassemble/scan/twain.pas
+++ b/reassemble/scan/twain.pas
@@ -1,7 +1,7 @@
{ ==============================================================================
方法名稱:StatrTwainScan
- 引用相依:TTiffGraphic, StatrTwainScan, Scanner, Scanner.OpenSource, Scanner.C
- loseSource, OnAcquire, Scanner.AcquireWithSourceOpen
+ 引用相依:OnAcquire, Scanner, Scanner.AcquireWithSourceOpen, Scanner.CloseSour
+ ce, Scanner.OpenSource, StatrTwainScan, TTiffGraphic
方法描述:啟動 TWAIN 掃瞄流程。此方法首先檢查掃瞄器驅動是否已安裝,接著初始化 Sc
anInfo 結構並設定掃瞄參數(如 DPI、影像格式、是否顯示 UI、雙面掃瞄模式、
亮度與對比)。流程中會開啟掃瞄來源,呼叫 AcquireWithSourceOpen 執行實際
@@ -65,7 +65,7 @@
{ ==============================================================================
方法名稱:OnAcquire
- 引用相依:TTiffGraphic, TJpegGraphic, OnAcquire
+ 引用相依:OnAcquire, TJpegGraphic, TTiffGraphic
方法描述:掃瞄影像獲取後的回呼處理函數。核心邏輯包含:
1. 將獲取的 DIB 句柄轉為影像對象並設定 DPI。
2. 依影像格式執行對應處理:黑白影像會進行條碼辨識、依條碼角度旋轉、影像
@@ -378,8 +378,8 @@
{ ==============================================================================
方法名稱:PageEnd
- 引用相依:GetNoNameCase, DirectoryExists, _DelTree, Str2Dir, SaveToFile, PageE
- nd
+ 引用相依:DirectoryExists, GetNoNameCase, PageEnd, SaveToFile, Str2Dir, _DelTr
+ ee
方法描述:管理掃瞄影像的儲存路徑與檔案命名規則。主要邏輯如下:
1. 辨識條碼以取得 FormID,並判斷是否為導引頁或分案頁。
2. 若偵測到分案頁,會重置計數並嘗試取得新的案件編號(CaseID)。
@@ -661,7 +661,7 @@
{ ==============================================================================
方法名稱:GetDefScanIni
- 引用相依:Rotate, FJpgCompression, Scanner
+ 引用相依:FJpgCompression, Rotate, Scanner
方法描述:從資料庫參數清單(WORK_INF_List)初始化並設定掃瞄的系統預設值。流程首先
設定一組程式內建的預設數值,隨後遍歷 WORK_INF_List 並比對 PARA_NO 關
鍵字,動態更新包含:空白頁判斷大小、影像是否反相、清黑邊、掃瞄 DPI、雙面掃
@@ -849,7 +849,7 @@
{ ==============================================================================
方法名稱:initkscan
- 引用相依:initkscan, Scanner, Scanner.OpenSource, Scanner.CloseSource
+ 引用相依:Scanner, Scanner.CloseSource, Scanner.OpenSource, initkscan
方法描述:初始化並偵測掃瞄器硬體能力。此方法會先將雙面掃瞄勾選框(ScanDuplexCB)
設為停用,接著嘗試開啟掃瞄來源(OpenSource),檢查掃瞄器是否支援雙面掃瞄
功能(DuplexCap > 0)。如果硬體支援,則啟用 UI 上的勾選框供使用者選擇。最
diff --git a/reassemble/transp/fileClient.pas b/reassemble/transp/fileClient.pas
index a263192..460ea8f 100644
--- a/reassemble/transp/fileClient.pas
+++ b/reassemble/transp/fileClient.pas
@@ -89,7 +89,7 @@
{ ==============================================================================
方法名稱:SetFtpInfo
- 引用相依:SetFtpInfo, IIS_Ftp
+ 引用相依:IIS_Ftp, SetFtpInfo
方法描述:將 FTP 連線參數與事件回呼設定至 FTP 傳輸元件 (IIS_Ftp)。此方法會將先
前取得並解碼的連線資訊(如 FTP IP、帳號、密碼、路徑、連接埠)指派給 IIS_Ft
p 物件,並根據協定類型設定是否開啟 SSL/TLS 以及被動模式 (Passive)。此
diff --git a/reassemble/view/mermaid/ActiveFormKeyUp.md b/reassemble/view/mermaid/ActiveFormKeyUp.md
new file mode 100644
index 0000000..eedfaf2
--- /dev/null
+++ b/reassemble/view/mermaid/ActiveFormKeyUp.md
@@ -0,0 +1,16 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckFocus{文字輸入框取得焦點?}
+ CheckFocus -- 否 --> End([結束])
+ CheckFocus -- 是 --> CheckISB{是否有選取影像?}
+
+ CheckISB -- 是 --> MatchKey{判斷按鍵}
+ CheckISB -- 否 --> End
+
+ MatchKey -- VK_UP (上) --> CallPrior[呼叫 PriorPage 翻頁]
+ MatchKey -- VK_DOWN (下) --> CallNext[呼叫 NextPage 翻頁]
+
+ CallPrior --> ScrollUI[同步滾動捲軸更新顯示]
+ CallNext --> ScrollUI
+ ScrollUI --> End
+```
diff --git a/reassemble/view/mermaid/AddAttFileLBClick.md b/reassemble/view/mermaid/AddAttFileLBClick.md
new file mode 100644
index 0000000..5ac3611
--- /dev/null
+++ b/reassemble/view/mermaid/AddAttFileLBClick.md
@@ -0,0 +1,21 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> SetFilter[設定副檔名過濾為 PDF]
+ SetFilter --> OpenDlg[開啟多選檔案對話框]
+ OpenDlg -- 使用者取消 --> End([結束])
+ OpenDlg -- 執行 --> ShowLoading[顯示載入中提示]
+
+ ShowLoading --> LoopFiles[遍歷選取的檔案]
+ LoopFiles --> CheckDup{檔案是否已存在?}
+ CheckDup -- 是 --> AskOver[詢問是否覆蓋]
+ CheckDup -- 否 --> CopyProc[執行 CopyFile 複製到案件目錄]
+
+ AskOver -- 否 --> NextFile[處理下一個檔案]
+ AskOver -- 是 --> DelOld[刪除舊紀錄] --> CopyProc
+
+ CopyProc --> UpdateList[更新附加檔案清單並顯示]
+ UpdateList --> NextFile
+
+ NextFile --> LoopFiles
+ LoopFiles -- 結束 --> HideLoading[停止載入提示] --> End
+```
diff --git a/reassemble/view/mermaid/AddScanBtnClick.md b/reassemble/view/mermaid/AddScanBtnClick.md
new file mode 100644
index 0000000..613a3e6
--- /dev/null
+++ b/reassemble/view/mermaid/AddScanBtnClick.md
@@ -0,0 +1,11 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckCase{是否選取案件?}
+ CheckCase -- 否 --> ShowMsg[提示先選案件] --> End([結束])
+ CheckCase -- 是 --> SetMode[設定掃描模式為插入模式 smInsert]
+
+ SetMode --> CallScan[呼叫 StatrTwainScan 執行追加掃描]
+ CallScan --> Redraw[重新繪製樹狀結構並更新筆數]
+ Redraw --> ClearLog[清空該案檢核記錄]
+ ClearLog --> AutoFocus[自動選取新文件節點並顯示] --> End
+```
diff --git a/reassemble/view/mermaid/DesableImage.md b/reassemble/view/mermaid/DesableImage.md
new file mode 100644
index 0000000..aaf8d1b
--- /dev/null
+++ b/reassemble/view/mermaid/DesableImage.md
@@ -0,0 +1,10 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ResetClick[重置 NowClick 點選狀態為 -1]
+ ResetClick --> LoopFC[遍歷功能按鈕 FC0 至 FC6]
+ LoopFC --> GetGray[從 ImageList 獲取灰階圖示並指派給按鈕]
+ GetGray --> NextFC[下一個按鈕]
+ NextFC --> LoopFC
+ LoopFC -- 結束 --> ResetMouse[將所有 ISB 設為一般使用者模式 mmUser]
+ ResetMouse --> End([結束])
+```
diff --git a/reassemble/view/mermaid/DisplayMode.md b/reassemble/view/mermaid/DisplayMode.md
new file mode 100644
index 0000000..ea26d0d
--- /dev/null
+++ b/reassemble/view/mermaid/DisplayMode.md
@@ -0,0 +1,15 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> HideAll[隱藏所有影像面板 imgp1-imgp8]
+ HideAll --> CalcSize[根據 BasePanel 寬高與網格行列計算面板尺寸]
+ CalcSize --> LoopGrid[雙重迴圈處理行列排列]
+
+ LoopGrid --> Position[計算每個面板的 Left 與 Top 座標]
+ Position --> ShowPl[顯示對應面板並設定寬高與位置]
+ ShowPl --> NextGrid[下一個網格位置]
+ NextGrid --> LoopGrid
+
+ LoopGrid -- 結束 --> AdjustShape[調整標記框 Shape1 大小並顯示]
+ AdjustShape --> UpdateBtn[更新工具列模式圖示]
+ UpdateBtn --> FocusISB[初始化首個視窗焦點 ISB1] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/DocNoIsExistImg.md b/reassemble/view/mermaid/DocNoIsExistImg.md
new file mode 100644
index 0000000..c944e73
--- /dev/null
+++ b/reassemble/view/mermaid/DocNoIsExistImg.md
@@ -0,0 +1,11 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> InitRes[初始化結果為 False]
+ InitRes --> LoadCtx[讀取目錄中的 Context.dat]
+ LoadCtx --> LoopImgs[遍歷清單中的所有檔名]
+ LoopImgs --> CheckExist{實際檔案是否存在?}
+ CheckExist -- 是 --> SetFound[發現影像, 返回 False] --> End([結束])
+ CheckExist -- 否 --> NextImg[檢查下一個檔案]
+ NextImg --> LoopImgs
+ LoopImgs -- 結束且未發現 --> SetEmpty[返回 True, 表示無影像] --> End
+```
diff --git a/reassemble/view/mermaid/EnableImage.md b/reassemble/view/mermaid/EnableImage.md
new file mode 100644
index 0000000..3b7d85b
--- /dev/null
+++ b/reassemble/view/mermaid/EnableImage.md
@@ -0,0 +1,8 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CallDisable[呼叫 DesableImage 停用既有功能]
+ CallDisable --> GetBmp[從 ImageList 獲取指定功能的彩色圖示]
+ GetBmp --> SetGlyph[將圖示指派給點選的按鈕]
+ SetGlyph --> CallMode[呼叫 ViewMouseMode 切換滑鼠作業模式]
+ CallMode --> End([結束])
+```
diff --git a/reassemble/view/mermaid/FindISB2View.md b/reassemble/view/mermaid/FindISB2View.md
new file mode 100644
index 0000000..c1d6349
--- /dev/null
+++ b/reassemble/view/mermaid/FindISB2View.md
@@ -0,0 +1,19 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ModeMap[根據檢視模式確定可見 ISB 數量 n]
+ ModeMap --> LoopISB[遍歷 ISB1 至 ISB8]
+
+ LoopISB --> Boundary{索引 i > n?}
+ Boundary -- 是 --> EndLoop
+ Boundary -- 否 --> CheckFull{索引 i = n 且已載入?}
+
+ CheckFull -- 是 --> ClearLast[呼叫 clearView 清空最後位置並傳回 ISB1]
+ CheckFull -- 否 --> CheckEmpty{ISB 檔名是否為空?}
+
+ CheckEmpty -- 是 --> ReturnISB[返回此 ISB 對象] --> End([結束])
+ CheckEmpty -- 否 --> NextISB[處理下一個索引]
+
+ NextISB --> LoopISB
+ EndLoop --> End
+ ClearLast --> End
+```
diff --git a/reassemble/view/mermaid/GoViewMode.md b/reassemble/view/mermaid/GoViewMode.md
new file mode 100644
index 0000000..139c355
--- /dev/null
+++ b/reassemble/view/mermaid/GoViewMode.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> MatchVMode{判斷 VMode 索引}
+ MatchVMode -- 0 (單頁) --> CallDisp0[呼叫 DisplayMode 1x1 佈局]
+ MatchVMode -- 1 (兩頁) --> CallDisp1[呼叫 DisplayMode 1x1 佈局]
+ MatchVMode -- 2 (網格) --> CallDisp2[呼叫 DisplayMode 2x2 佈局]
+ MatchVMode -- 3 (自定義) --> CallDisp3[呼叫 DisplayMode 2x3 佈局]
+ MatchVMode -- 4 (擴展) --> CallDisp4[呼叫 DisplayMode 2x4 佈局]
+ CallDisp0 --> End([結束])
+ CallDisp1 --> End
+ CallDisp2 --> End
+ CallDisp3 --> End
+ CallDisp4 --> End
+```
diff --git a/reassemble/view/mermaid/ISB1Click.md b/reassemble/view/mermaid/ISB1Click.md
new file mode 100644
index 0000000..1d95dfc
--- /dev/null
+++ b/reassemble/view/mermaid/ISB1Click.md
@@ -0,0 +1,10 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> SetISB[將 Sender 設為當前 DisplayISB]
+ SetISB --> MoveShape[將 Shape1 選取框移動至該 ISB 位置]
+ MoveShape --> CalcPage[依據 ISB 名稱與捲軸位置計算頁碼 p]
+ CalcPage --> UpdatePageLV{p 是否在有效範圍內?}
+ UpdatePageLV -- 是 --> SyncUI[更新 NowPage 與 PageLV 的選取索引]
+ UpdatePageLV -- 否 --> End([結束])
+ SyncUI --> End
+```
diff --git a/reassemble/view/mermaid/ISB1ImageMouseDown.md b/reassemble/view/mermaid/ISB1ImageMouseDown.md
new file mode 100644
index 0000000..1e2ba46
--- /dev/null
+++ b/reassemble/view/mermaid/ISB1ImageMouseDown.md
@@ -0,0 +1,17 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> SetISB[設定當前 DisplayISB 並取得焦點]
+ SetISB --> SyncUI[更新 Shape1 選取框與 PageLV 選取頁面]
+ SyncUI --> ModeCheck{判斷當前模式}
+
+ ModeCheck -- 拖曳 (NowClick = -1) --> CheckLeft{是否按下左鍵且有圖?}
+ CheckLeft -- 是 --> StartDrag[啟動影像拖曳 BeginDrag]
+ CheckLeft -- 否 --> RotateCheck
+
+ ModeCheck -- 其他 --> RotateCheck{是否為旋轉模式?}
+ RotateCheck -- 是 --> LoadImg[重新載入影像檔案]
+ RotateCheck -- 否 --> End([結束])
+
+ StartDrag --> End
+ LoadImg --> End
+```
diff --git a/reassemble/view/mermaid/ISB1ImageMouseUp.md b/reassemble/view/mermaid/ISB1ImageMouseUp.md
new file mode 100644
index 0000000..1198519
--- /dev/null
+++ b/reassemble/view/mermaid/ISB1ImageMouseUp.md
@@ -0,0 +1,13 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> MouseMode{判斷滑鼠模式}
+
+ MouseMode -- 刪除 (mmDelete) --> CallDel[觸發右鍵選單刪除功能 PM508Click]
+ MouseMode -- 旋轉 (mmR90/180/270) --> SaveRotated[儲存旋轉後的檔案, 針對 JPG 設定品質]
+ MouseMode -- 縮放/拖曳 (mmZoom/mmDrag) --> SaveScroll[呼叫 SetScrollData 記錄捲軸位置]
+
+ SaveRotated --> SyncPreview[同步更新預覽圖 SelectISB 並清空檢核記錄]
+ SyncPreview --> SaveScroll
+ CallDel --> End([結束])
+ SaveScroll --> End
+```
diff --git a/reassemble/view/mermaid/Initialize.md b/reassemble/view/mermaid/Initialize.md
new file mode 100644
index 0000000..9c42d34
--- /dev/null
+++ b/reassemble/view/mermaid/Initialize.md
@@ -0,0 +1,9 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> InheritInit[呼叫繼承的 Initialize]
+ InheritInit --> RegEvents[註冊視窗與滑鼠事件處理函式]
+ RegEvents --> SetDefaults[設定預設參數: MpsKey, Seg, Ext, SafePixel]
+ SetDefaults --> SetLengths[設定案件與表單編號長度限制]
+ SetLengths --> SetOther[設定去直線容忍值與切圖條碼類型]
+ SetOther --> End([結束])
+```
diff --git a/reassemble/view/mermaid/NewScanBtnClick.md b/reassemble/view/mermaid/NewScanBtnClick.md
new file mode 100644
index 0000000..f808b01
--- /dev/null
+++ b/reassemble/view/mermaid/NewScanBtnClick.md
@@ -0,0 +1,13 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckInit{初始化是否完成?}
+ CheckInit -- 否 --> ShowWait[提示稍候] --> End([結束])
+ CheckInit -- 是 --> SpecialMode{檢查特殊模式: RSCAN/ESCAN/DSCAN?}
+
+ SpecialMode -- 是 --> AutoSelect[自動選取新件節點並觸發追加掃描]
+ SpecialMode -- 否 --> NewScan[全新掃描: 重置模式與路徑, 清空清單]
+
+ AutoSelect --> End
+ NewScan --> CallScan[呼叫 StatrTwainScan 啟動掃描]
+ CallScan --> Reload[掃描結束, 重新載入影像檔案] --> End
+```
diff --git a/reassemble/view/mermaid/NextPageBtnClick.md b/reassemble/view/mermaid/NextPageBtnClick.md
new file mode 100644
index 0000000..3b1e3d8
--- /dev/null
+++ b/reassemble/view/mermaid/NextPageBtnClick.md
@@ -0,0 +1,12 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckSelect{是否有選取影像?}
+ CheckSelect -- 否 --> End([結束])
+ CheckSelect -- 是 --> CallNext[呼叫 NextPage 跳轉]
+
+ CallNext --> CheckBound{新影像是否超出可見高度?}
+ CheckBound -- 是 --> AdjustScroll[自動調整垂直捲軸位置]
+ CheckBound -- 否 --> End
+
+ AdjustScroll --> End
+```
diff --git a/reassemble/view/mermaid/OptionBtnClick.md b/reassemble/view/mermaid/OptionBtnClick.md
new file mode 100644
index 0000000..c041987
--- /dev/null
+++ b/reassemble/view/mermaid/OptionBtnClick.md
@@ -0,0 +1,18 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ShowLoading[顯示載入中提示]
+ ShowLoading --> CreateDlg[建立 TPatchDlg 對話框]
+ CreateDlg --> InitI18n[載入多國語言設定]
+ InitI18n --> SyncParams[將系統參數同步至對話框控制項]
+ SyncParams --> ShowDlg[顯示對話框供使用者編輯]
+
+ ShowDlg -- 使用者按確定 --> SaveParams[將新參數存回系統變數]
+ ShowDlg -- 使用者按取消 --> EndProc[結束處理]
+
+ SaveParams --> WriteIni[呼叫 R_W_ScanIni 寫入設定檔]
+ WriteIni --> UpdateUI[同步更新 UI 勾選狀態]
+
+ UpdateUI --> EndProc
+ EndProc --> FreeDlg[釋放對話框資源]
+ FreeDlg --> HideLoading[停止載入提示] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM101Click.md b/reassemble/view/mermaid/PM101Click.md
new file mode 100644
index 0000000..a7ab099
--- /dev/null
+++ b/reassemble/view/mermaid/PM101Click.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckLevel{判斷選取節點層級}
+
+ CheckLevel -- 根節點/全刪 --> DelAll[刪除所有案件實體目錄並重載]
+ CheckLevel -- 案件層 --> DelCase[刪除案件目錄, 更新案件清單與索引]
+ CheckLevel -- 文件層 --> DelDoc[判斷模式, 呼叫 DeleteDocNoFileForESCAN 或刪除目錄]
+ CheckLevel -- 表單層 --> DelForm[呼叫 DeleteFormCodeFile 刪除表單影像]
+
+ DelAll --> End([結束])
+ DelCase --> ClearErr[清空檢核記錄] --> End
+ DelDoc --> ClearErr
+ DelForm --> UpdateUI[更新樹狀頁數統計與刷新] --> End
+```
diff --git a/reassemble/view/mermaid/PM102Click.md b/reassemble/view/mermaid/PM102Click.md
new file mode 100644
index 0000000..ed5c18c
--- /dev/null
+++ b/reassemble/view/mermaid/PM102Click.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> AskNewID[彈出輸入盒要求輸入新編號]
+ AskNewID --> ValidCheck{驗證長度與是否重複?}
+
+ ValidCheck -- 失敗 --> ShowErr[顯示錯誤訊息] --> End([結束])
+ ValidCheck -- 成功 --> Confirm[詢問是否確認修改]
+
+ Confirm -- 是 --> ExecRename[清空顯示, 執行磁碟目錄更名]
+ Confirm -- 否 --> End
+
+ ExecRename --> UpdateList[更新案件清單文字]
+ UpdateList --> Redraw[重新繪製樹狀結構並提示完成] --> End
+```
diff --git a/reassemble/view/mermaid/PM104Click.md b/reassemble/view/mermaid/PM104Click.md
new file mode 100644
index 0000000..0bd9c90
--- /dev/null
+++ b/reassemble/view/mermaid/PM104Click.md
@@ -0,0 +1,23 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> OpenDlg[開啟檔案對話框選取影像]
+ OpenDlg -- 執行 --> SizeCheck{檔案大小是否超過限制?}
+ SizeCheck -- 是 --> ShowErr[顯示超過限制訊息] --> End([結束])
+
+ SizeCheck -- 否 --> ShowLoading[顯示載入中提示]
+ ShowLoading --> LoopPages[逐頁載入影像並執行去偏斜]
+
+ LoopPages --> BarcodeProc[條碼辨識判斷 FormID 與旋轉]
+ BarcodeProc --> CropCheck{是否需 A3 切圖?}
+ CropCheck -- 是 --> PerformCrop[左右分割影像]
+ CropCheck -- 否 --> SingleImg[處理單張影像]
+
+ PerformCrop --> SaveProc[轉換格式: 黑白轉 TIF, 彩色轉 JPG 並存檔]
+ SingleImg --> SaveProc
+
+ SaveProc --> UpdateCtx[更新索引與樹狀結構頁數統計]
+ UpdateCtx --> NextPage[處理下一頁]
+
+ NextPage --> LoopPages
+ LoopPages -- 結束 --> ClearLog[清空檢核記錄並重載顯示] --> End
+```
diff --git a/reassemble/view/mermaid/PM106Click.md b/reassemble/view/mermaid/PM106Click.md
new file mode 100644
index 0000000..93376d0
--- /dev/null
+++ b/reassemble/view/mermaid/PM106Click.md
@@ -0,0 +1,28 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ShowLoading[顯示載入中提示]
+ ShowLoading --> CreateForm[建立 TDocCopyForm 對話框]
+ CreateForm --> InitI18n[載入多國語言與來源案件編號]
+ InitI18n --> LoadDocs[從樹狀結構載入可複製的文件清單]
+ LoadDocs --> LoadCases[從樹狀結構載入目標案件清單]
+
+ LoadCases --> ShowDlg[顯示對話框]
+ ShowDlg -- mrOk (確認) --> AskConfirm[詢問是否確定執行複製]
+ ShowDlg -- 取消 --> EndProc[結束處理]
+
+ AskConfirm -- 是 --> LoopTargets[遍歷選取的目標案件]
+ LoopTargets --> LoopDocs[遍歷選取的來源文件]
+
+ LoopDocs --> ExecCopy[執行 CopyFile 並更新目標案件 Context.dat]
+ ExecCopy --> ClearErr[清空目標案件檢核記錄]
+ ClearErr --> NextDoc[下一個文件]
+
+ NextDoc --> LoopDocs
+ LoopDocs -- 結束 --> NextCase[下一個案件]
+ NextCase --> LoopTargets
+
+ LoopTargets -- 結束 --> Reload[重新載入影像並提示完成]
+
+ Reload --> EndProc
+ EndProc --> FreeRes[釋放資源並停止提示] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM108Click.md b/reassemble/view/mermaid/PM108Click.md
new file mode 100644
index 0000000..8167612
--- /dev/null
+++ b/reassemble/view/mermaid/PM108Click.md
@@ -0,0 +1,25 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CreateDlg[建立 TDocListForm]
+ CreateDlg --> LoadForms[從 FORM_INF_List 載入可用表單]
+ LoadForms --> ShowDlg[顯示對話框]
+
+ ShowDlg -- mrOk (確認) --> CheckCustom{是否歸類至自定義?}
+ ShowDlg -- 取消 --> EndProc[結束處理]
+
+ CheckCustom -- 是 --> NewFormID[取得自定義名稱與編號]
+ CheckCustom -- 否 --> ExistFormID[取得選取的既有 FormID]
+
+ NewFormID --> AskConfirm[詢問是否將所有影像歸類]
+ ExistFormID --> AskConfirm
+
+ AskConfirm -- 是 --> ExecReplace[呼叫 FormIDReplace 搬移影像檔案]
+ AskConfirm -- 否 --> EndProc
+
+ ExecReplace --> UpdateTree[更新索引與樹狀結構顯示]
+ UpdateTree --> ClearLog[清空檢核記錄]
+ ClearLog --> RestoreFocus[焦點回到案件節點並刷新]
+
+ RestoreFocus --> EndProc
+ EndProc --> FreeRes[釋放資源] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM109Click.md b/reassemble/view/mermaid/PM109Click.md
new file mode 100644
index 0000000..94f768d
--- /dev/null
+++ b/reassemble/view/mermaid/PM109Click.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ClearView[清空目前影像顯示]
+ ClearView --> ShowLoading[顯示 OMR 檢核中提示]
+ ShowLoading --> CallCheck[呼叫 OMRCheckCase 執行案件檢核]
+
+ CallCheck --> CheckOk{檢核是否成功?}
+ CheckOk -- 是 --> CreateMark[建立 OMRCheckOk.dat 標記檔]
+ CheckOk -- 否 --> EndProc[結束處理]
+
+ CreateMark --> EndProc
+ EndProc --> Reload[重載影像並刷新樹狀結構]
+ Reload --> ShowMsg[提示檢核完成] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM110Click.md b/reassemble/view/mermaid/PM110Click.md
new file mode 100644
index 0000000..5a522d6
--- /dev/null
+++ b/reassemble/view/mermaid/PM110Click.md
@@ -0,0 +1,12 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> AskName[要求輸入其他文件名稱]
+ AskName -- 確認 --> CheckDup{名稱是否已存在?}
+ AskName -- 取消 --> End([結束])
+
+ CheckDup -- 是 --> ShowErr[提示名稱已存在] --> End
+ CheckDup -- 否 --> GenID[產生新文件編號與建立子目錄]
+
+ GenID --> SyncList[將新目錄加入清單並繪製樹狀結構]
+ SyncList --> AutoExpand[自動展開新建立的節點] --> End
+```
diff --git a/reassemble/view/mermaid/PM111Click.md b/reassemble/view/mermaid/PM111Click.md
new file mode 100644
index 0000000..397fbf6
--- /dev/null
+++ b/reassemble/view/mermaid/PM111Click.md
@@ -0,0 +1,17 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> GetOld[取得目前文件份數]
+ GetOld --> AskNew[彈出輸入盒供使用者修改份數]
+
+ AskNew --> ValidRange{輸入是否在 1-9999 範圍內?}
+ ValidRange -- 否 --> ShowErr[顯示輸入錯誤] --> End([結束])
+ ValidRange -- 是 --> CheckDiv{是否為分份文件且設為 1?}
+
+ CheckDiv -- 是 --> AskConfirm[詢問是否確定修改並限制後續更動]
+ CheckDiv -- 否 --> ExecUpdate[更新 SetDocDirCopies 並標記已編輯]
+
+ AskConfirm -- 確認 --> ExecUpdate
+ AskConfirm -- 取消 --> End
+
+ ExecUpdate --> Redraw[刷新樹狀結構統計並提示完成] --> End
+```
diff --git a/reassemble/view/mermaid/PM401Click.md b/reassemble/view/mermaid/PM401Click.md
new file mode 100644
index 0000000..13d26e7
--- /dev/null
+++ b/reassemble/view/mermaid/PM401Click.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckIndex{選取索引是否為第一頁?}
+ CheckIndex -- 是 --> ShowErr[提示不能從第一頁分案] --> End([結束])
+ CheckIndex -- 否 --> AskConfirm[詢問是否確定分案]
+
+ AskConfirm -- 否 --> End
+ AskConfirm -- 是 --> Prepare[清空檢核記錄並取得新流水案號]
+
+ Prepare --> LoopMove[搬移指定頁碼後的所有影像至新目錄]
+ LoopMove --> UpdateDat[同步更新原案與新案的 Context.dat]
+ UpdateDat --> SyncIndex[寫入案件索引 CaseIndex.dat]
+ SyncIndex --> Reload[重新載入影像列表並提示完成] --> End
+```
diff --git a/reassemble/view/mermaid/PM404Click.md b/reassemble/view/mermaid/PM404Click.md
new file mode 100644
index 0000000..19153f3
--- /dev/null
+++ b/reassemble/view/mermaid/PM404Click.md
@@ -0,0 +1,17 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ShowLoading[顯示載入中提示]
+ ShowLoading --> CreateDlg[建立 TDocListForm 表單清單]
+ CreateDlg --> LoadForms[從 FORM_INF_List 載入可用表單]
+ LoadForms --> ShowDlg[顯示對話框]
+
+ ShowDlg -- mrOk (確認) --> GetFormID[獲取選取的 FormID]
+ ShowDlg -- 取消 --> EndProc[結束處理]
+
+ GetFormID --> Reclassify[依 TreeView 層級呼叫 PageReplaceFormID]
+ Reclassify --> Redraw[重新繪製樹狀結構並清空檢核記錄]
+ Redraw --> RestoreFocus[回到原先選取的節點並點擊]
+
+ RestoreFocus --> EndProc
+ EndProc --> FreeRes[釋放資源並停止提示] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM505Click.md b/reassemble/view/mermaid/PM505Click.md
new file mode 100644
index 0000000..5425f17
--- /dev/null
+++ b/reassemble/view/mermaid/PM505Click.md
@@ -0,0 +1,10 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckFile{當前是否有載入影像?}
+ CheckFile -- 否 --> End([結束])
+ CheckFile -- 是 --> SetMode[設定掃描模式為 smReplace]
+
+ SetMode --> SetPath[指定儲存路徑與檔名為當前顯示之影像]
+ SetPath --> StartScan[呼叫 StatrTwainScan 執行掃描覆蓋]
+ StartScan --> ClearLog[清空該案件的檢核記錄] --> End
+```
diff --git a/reassemble/view/mermaid/PM507Click.md b/reassemble/view/mermaid/PM507Click.md
new file mode 100644
index 0000000..7fce0e6
--- /dev/null
+++ b/reassemble/view/mermaid/PM507Click.md
@@ -0,0 +1,17 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ShowLoading[顯示載入中提示]
+ ShowLoading --> CreateDlg[建立 TDocListForm]
+ CreateDlg --> LoadForms[載入可用表單]
+ LoadForms --> ShowDlg[顯示對話框]
+
+ ShowDlg -- mrOk (確認) --> CalcName[依 FormID 產生新的序號檔名]
+ ShowDlg -- 取消 --> EndProc[結束處理]
+
+ CalcName --> ExecRename[執行 RenameFile 更名並更新 Context.dat]
+ ExecRename --> Redraw[重新整理樹狀結構並清空檢核記錄]
+ Redraw --> RestoreFocus[焦點回到原文件節點並點擊]
+
+ RestoreFocus --> EndProc
+ EndProc --> FreeRes[釋放資源] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM508Click.md b/reassemble/view/mermaid/PM508Click.md
new file mode 100644
index 0000000..e2d1936
--- /dev/null
+++ b/reassemble/view/mermaid/PM508Click.md
@@ -0,0 +1,20 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckLast{是否為案件最後一張影像?}
+ CheckLast -- 是 --> AskDelCase[詢問是否刪除整個案件]
+ CheckLast -- 否 --> AskDelImg[詢問是否確定刪除影像]
+
+ AskDelCase -- 是 --> DelTree[執行 _DelTree 刪除案件目錄]
+ AskDelCase -- 否 --> End([結束])
+
+ AskDelImg -- 是 --> ExecDel[從清單移除項目, 刪除實體檔案]
+ AskDelImg -- 否 --> End
+
+ ExecDel --> ReSort[呼叫 ReSortFileName 重新排序檔案]
+ ReSort --> UpdateTree[更新樹狀結構統計與顯示]
+ UpdateTree --> ClearLog[清空檢核記錄]
+
+ DelTree --> Reload[重載影像檔案清單]
+ ClearLog --> End
+ Reload --> End
+```
diff --git a/reassemble/view/mermaid/PM601Click.md b/reassemble/view/mermaid/PM601Click.md
new file mode 100644
index 0000000..75f38c1
--- /dev/null
+++ b/reassemble/view/mermaid/PM601Click.md
@@ -0,0 +1,21 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ShowLoading[顯示載入中提示]
+ ShowLoading --> CreateDlg[建立 TDocListForm]
+ CreateDlg --> LoopSelected[遍歷縮圖區選取的影像]
+
+ LoopSelected --> GetTarget{選擇歸類目標}
+ GetTarget -- 既有表單 --> CalcPath[判斷是否分份, 確定儲存目錄]
+ GetTarget -- 自定義 --> NewDir[產生新文件編號與目錄]
+
+ CalcPath --> FileOp[執行檔案複製與刪除原檔案]
+ NewDir --> FileOp
+
+ FileOp --> UpdateCtx[更新目標與原目錄的 ContextList]
+ UpdateCtx --> NextImg[處理下一個選取影像]
+
+ NextImg --> LoopSelected
+ LoopSelected -- 結束 --> ReSort[執行檔案重新排序]
+ ReSort --> Redraw[更新樹狀結構並清空檢核記錄]
+ Redraw --> FreeRes[釋放資源並停止提示] --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM602Click.md b/reassemble/view/mermaid/PM602Click.md
new file mode 100644
index 0000000..7cd3f6a
--- /dev/null
+++ b/reassemble/view/mermaid/PM602Click.md
@@ -0,0 +1,20 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> AskName[彈出對話框要求輸入文件名稱]
+ AskName -- 確認 --> CheckDup{名稱是否已存在?}
+ AskName -- 取消 --> End([結束])
+
+ CheckDup -- 是 --> ShowErr[提示名稱已存在] --> End
+ CheckDup -- 否 --> GenID[產生新的自定義文件編號與目錄]
+
+ GenID --> SyncList[將新目錄加入清單並更新編輯狀態]
+ SyncList --> LoopSelected[遍歷選取的影像]
+
+ LoopSelected --> ExecCopy[執行 CopyFile 與 SetContextList]
+ ExecCopy --> ExecDel[呼叫 DeleteImageFile 刪除原檔案]
+ ExecDel --> NextImg[下一個影像]
+
+ NextImg --> LoopSelected
+ LoopSelected -- 結束 --> ReSort[重新排序檔案並刷新顯示]
+ ReSort --> UpdateTree[更新樹狀結構並清空檢核記錄] --> End
+```
diff --git a/reassemble/view/mermaid/PM604Click.md b/reassemble/view/mermaid/PM604Click.md
new file mode 100644
index 0000000..d73b596
--- /dev/null
+++ b/reassemble/view/mermaid/PM604Click.md
@@ -0,0 +1,11 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> LoopComps[遍歷縮圖區選取的影像元件]
+ LoopComps --> FindISB[尋找對應的 TImageScrollBox]
+ FindISB --> ExecDeskew[執行 DeskewImg 自動去偏斜]
+ ExecDeskew --> Redraw[重新繪製影像並存回原檔案]
+ Redraw --> SyncMain[更新主顯示區影像]
+ SyncMain --> NextComp[處理下一個元件]
+ NextComp --> LoopComps
+ LoopComps -- 結束 --> End([結束])
+```
diff --git a/reassemble/view/mermaid/PM605Click.md b/reassemble/view/mermaid/PM605Click.md
new file mode 100644
index 0000000..b657a8c
--- /dev/null
+++ b/reassemble/view/mermaid/PM605Click.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> AskConfirm[詢問是否確定刪除?]
+ AskConfirm -- 否 --> End([結束])
+ AskConfirm -- 是 --> LoopSelected[遍歷所有由 Shape 標記的選取影像]
+
+ LoopSelected --> CallDel[呼叫 DeleteImageFile 刪除實際檔案]
+ CallDel --> NextImg[處理下一個]
+
+ NextImg --> LoopSelected
+ LoopSelected -- 結束 --> ReSort[執行檔案重新排序 ReSortFileName]
+ ReSort --> UpdateTree[更新樹狀結構頁數統計與刷新顯示]
+ UpdateTree --> ClearLog[清空案件檢核記錄] --> End
+```
diff --git a/reassemble/view/mermaid/PopupMenu1Popup.md b/reassemble/view/mermaid/PopupMenu1Popup.md
new file mode 100644
index 0000000..881f730
--- /dev/null
+++ b/reassemble/view/mermaid/PopupMenu1Popup.md
@@ -0,0 +1,19 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> HideAll[隱藏 PM101 至 PM111 所有項]
+ HideAll --> CheckSelect{是否有選取節點?}
+ CheckSelect -- 否 --> End([結束])
+ CheckSelect -- 是 --> LevelCheck{判斷選取層級}
+
+ LevelCheck -- 根節點 --> NewScanItems[顯示刪除, 掃描加入, 檔案加入]
+ LevelCheck -- 案件層 --> CaseItems[顯示刪除, 掃描加入, 寫備註, 檢核, 檔案加入等]
+ LevelCheck -- 文件層 --> DocItems[顯示刪除, 修改份數, 修改編號等]
+ LevelCheck -- 表單層 --> FormItems[顯示刪除, 歸類, 掃描加入, 檔案加入等]
+
+ CaseItems --> AuthCheck[根據 FImgDelete 與 CaseDelete_Enable 設定可用性]
+ DocItems --> AuthCheck
+ FormItems --> AuthCheck
+
+ AuthCheck --> End
+ NewScanItems --> End
+```
diff --git a/reassemble/view/mermaid/PopupMenu6Popup.md b/reassemble/view/mermaid/PopupMenu6Popup.md
new file mode 100644
index 0000000..744d389
--- /dev/null
+++ b/reassemble/view/mermaid/PopupMenu6Popup.md
@@ -0,0 +1,14 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> InitVisibility[設定預設可見性: 歸類, 自定義, 刪除為 True]
+ InitVisibility --> CheckDoc{是否為附件目錄?}
+
+ CheckDoc -- 是 --> ExtraItems[顯示歪斜矯正, 自定義等所有功能]
+ CheckDoc -- 否 --> ModeCheck{是否為異動件模式?}
+
+ ExtraItems --> AuthCheck[根據 FImgDelete 權限與 UseCase 引用狀態設定可用性]
+ ModeCheck -- 是 --> HideItems[隱藏部分歸類功能] --> AuthCheck
+ ModeCheck -- 否 --> AuthCheck
+
+ AuthCheck --> End([結束])
+```
diff --git a/reassemble/view/mermaid/SampleScanBtnClick.md b/reassemble/view/mermaid/SampleScanBtnClick.md
new file mode 100644
index 0000000..30a916d
--- /dev/null
+++ b/reassemble/view/mermaid/SampleScanBtnClick.md
@@ -0,0 +1,21 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> SetMode[設定掃描模式為範本模式 smSample]
+ SetMode --> SetUI[切換單頁顯示並重置計數]
+ SetUI --> InputFormID[引導使用者輸入 FormID]
+
+ InputFormID --> CheckReg{FormID 是否已註冊?}
+ CheckReg -- 否 --> ShowErr[顯示未註冊訊息] --> End([結束])
+ CheckReg -- 是 --> StartScan[呼叫 StatrTwainScan 執行掃描]
+
+ StartScan --> CheckFile{是否成功產生 TIF 影像?}
+ CheckFile -- 否 --> End
+ CheckFile -- 是 --> GenJPG[產生 JPG 預覽圖]
+
+ GenJPG --> UploadTIF[透過 HTTPS 上傳 TIF 範本]
+ UploadTIF --> CheckSess{Session 是否有效?}
+ CheckSess -- 否 --> ShowLogin[提示重新登入] --> End
+ CheckSess -- 是 --> UploadJPG[上傳 JPG 影像]
+
+ UploadJPG --> Success[提示傳送完成] --> End
+```
diff --git a/reassemble/view/mermaid/TransBtnClick.md b/reassemble/view/mermaid/TransBtnClick.md
new file mode 100644
index 0000000..57ecb42
--- /dev/null
+++ b/reassemble/view/mermaid/TransBtnClick.md
@@ -0,0 +1,26 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> CheckPre[完整前置檢查: 配號, 歸類, 時間限制]
+ CheckPre --> AllPass{檢查是否通過?}
+ AllPass -- 否 --> End([結束])
+ AllPass -- 是 --> ShowLoading[顯示上傳中提示]
+
+ ShowLoading --> LoopCases[遍歷所有案件]
+ LoopCases --> Prepare[產生入庫文件檔與影像結構]
+ Prepare --> AskServer{詢問伺服器是否可上傳?}
+
+ AskServer -- 否/重複 --> LogCount[更新統計並跳過]
+ AskServer -- 是 --> ProcCase[執行 CaseReSize 與 OMR 檢核]
+
+ ProcCase --> CheckOk{檢核是否通過?}
+ CheckOk -- 否 --> LogErr[記錄檢核失敗案件]
+ CheckOk -- 是 --> CallTrans[呼叫 TransCaseID 執行封裝傳送]
+
+ CallTrans --> NextCase[處理下一個案件]
+ LogCount --> NextCase
+ LogErr --> NextCase
+
+ NextCase --> LoopCases
+ LoopCases -- 結束 --> ShowReport[顯示成功/失敗統計報告]
+ ShowReport --> Reload[重新載入影像並結束] --> End
+```
diff --git a/reassemble/view/mermaid/ViewMouseMode.md b/reassemble/view/mermaid/ViewMouseMode.md
new file mode 100644
index 0000000..b0c9a9f
--- /dev/null
+++ b/reassemble/view/mermaid/ViewMouseMode.md
@@ -0,0 +1,9 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> MapMode[依參數 v 對應至 mmAmplifier, mmZoom, mmDrag, mmDelete 等]
+ MapMode --> LoopISB[遍歷所有影像捲軸盒 ISB1-ISB8]
+ LoopISB --> SetMouse[將對應的 MouseMode 指派給元件]
+ SetMouse --> NextISB[處理下一個]
+ NextISB --> LoopISB
+ LoopISB -- 結束 --> End([結束])
+```
diff --git a/reassemble/view/mermaid/WNoteBtnClick.md b/reassemble/view/mermaid/WNoteBtnClick.md
new file mode 100644
index 0000000..c8f9aac
--- /dev/null
+++ b/reassemble/view/mermaid/WNoteBtnClick.md
@@ -0,0 +1,17 @@
+```mermaid
+flowchart TD
+ Start([開始]) --> ShowLoading[顯示載入中提示]
+ ShowLoading --> CreateForm[建立 TSortMemoForm 編輯視窗]
+ CreateForm --> InitData[從 MEMO_INF_List 載入註記範本]
+ InitData --> LoadExisting[讀取既有 Scan_Memo.dat 內容並顯示]
+ LoadExisting --> ShowDlg[顯示編輯視窗]
+
+ ShowDlg -- mrOk (確認) --> SaveData[將編輯結果存回 Scan_Memo.dat]
+ ShowDlg -- 取消 --> FreeRes[釋放資源]
+
+ SaveData --> FreeRes
+ FreeRes --> HideLoading[停止載入提示]
+ HideLoading --> CheckRefresh{是否需要更新狀態?}
+ CheckRefresh -- 是 --> UpdateCase[觸發 CaseHelpBtnClick] --> End([結束])
+ CheckRefresh -- 否 --> End
+```
diff --git a/reassemble/view/misc.pas b/reassemble/view/misc.pas
index b355f71..aa17008 100644
--- a/reassemble/view/misc.pas
+++ b/reassemble/view/misc.pas
@@ -867,7 +867,7 @@
{ ==============================================================================
方法名稱:AddAttFileLBClick
- 引用相依:FileExists, CopyFile
+ 引用相依:CopyFile, FileExists
方法描述:處理「加入附加電子檔」按鈕點擊。開啟檔案對話框選取多個 PDF 檔案,支援覆
蓋檢查。執行 CopyFile 將檔案複製到案件目錄下,並呼叫 SetAttContextList
更新附加檔案清單後載入顯示。
@@ -1044,7 +1044,7 @@
{ ==============================================================================
方法名稱:Button5Click
- 引用相依:SetFtpInfo, IIS_Ftp
+ 引用相依:IIS_Ftp, SetFtpInfo
方法描述:測試 FTP 上傳功能。連線 FTP 後嘗試將特定的 PDF 檔案上傳至伺服器路徑。
============================================================================== }
procedure TCB_IMGPSScanX.Button5Click(Sender: TObject);
@@ -1059,7 +1059,7 @@
{ ==============================================================================
方法名稱:Button6Click
- 引用相依:SetFtpInfo, IIS_Ftp, Rotate, FJpgCompression, Scanner
+ 引用相依:FJpgCompression, IIS_Ftp, Rotate, Scanner, SetFtpInfo
方法描述:測試 FTP 下載功能。連線 FTP 後嘗試從伺服器下載 ZIP 案件檔至本地。
============================================================================== }
procedure TCB_IMGPSScanX.Button6Click(Sender: TObject);
@@ -1076,7 +1076,7 @@
{ ==============================================================================
方法名稱:ExportBtClick
- 引用相依:SaveToFile, FileExists, En_DecryptionStr_Base64, dnFile, dnFile_Get
+ 引用相依:En_DecryptionStr_Base64, FileExists, SaveToFile, dnFile, dnFile_Get
方法描述:處理「匯出授權檔」按鈕點擊。透過 HTTPS 下載掃瞄與檢視用的 .lic 授權檔案
。將授權檔連同加密的 mps.dat 檔案打包成帶有密碼保護的 mps.zip 壓縮包,
完成後清理暫存檔並提示路徑。
@@ -1147,8 +1147,8 @@
{ ==============================================================================
方法名稱:ImportBtClick
- 引用相依:Str2Dir, FileExists, LoadFromFile, RenameFile, _DelTree, En_Decrypti
- onStr_Base64, upFile
+ 引用相依:En_DecryptionStr_Base64, FileExists, LoadFromFile, RenameFile, Str2D
+ ir, _DelTree, upFile
方法描述:處理「匯入授權檔」按鈕點擊。選取 mps.zip 授權包後進行解壓與過期驗證。驗
證通過後對授權檔執行重新命名,並透過 upFile 函式逐一上傳至伺服器範本
目錄,過程中會嚴格檢查 Session 與回傳狀態。
@@ -1423,7 +1423,7 @@
{ ==============================================================================
方法名稱:CaseReSize
- 引用相依:ImageReSize_FormID, FileExists, LoadFromFile
+ 引用相依:FileExists, ImageReSize_FormID, ImageResize, LoadFromFile
方法描述:對案件執行影像縮放處理。清空舊有的檢核與定位錯誤記錄,隨後遍歷影像清單
,對每個檔案執行 ImageReSize_FormID 處理。
============================================================================== }
@@ -1453,8 +1453,8 @@
{ ==============================================================================
方法名稱:TransCaseID
- 引用相依:FileExists, LoadFromFile, CopyFile, FindFirst, _DelTree, upFile, Set
- FtpInfo, IIS_Ftp, FtpCaseComplete
+ 引用相依:CopyFile, FileExists, FindFirst, FtpCaseComplete, IIS_Ftp, LoadFromF
+ ile, SetFtpInfo, _DelTree, upFile
方法描述:傳送案件核心程序。包含排序影像、產生描述檔(FormID/DocNo對照、OMR資訊、附
件狀態等)、建立 ZIP 壓縮包(含主圖與遮罩)並檢查大小。最後根據 HTTP 或 F
TP 模式上傳至伺服器。上傳完成後針對異動模式處理舊件引入,並在最後清理
@@ -1823,8 +1823,8 @@
{ ==============================================================================
方法名稱:GetNode2Name
- 引用相依:FileExists, Str2Dir, SaveToFile, LoadFromFile, DeleteDocNoFile, Copy
- File, DirectoryExists, En_DecryptionStr_Base64, dnFile
+ 引用相依:CopyFile, DeleteDocNoFile, DirectoryExists, En_DecryptionStr_Base64,
+ FileExists, LoadFromFile, SaveToFile, Str2Dir, dnFile
方法描述:提取文件層級節點的識別名稱字串,用於記錄與恢復節點選取狀態。
============================================================================== }
Function TCB_IMGPSScanX.GetNode2Name(Node2:TTreeNode):String; //取MyTreeNode2的識別字出來(記之前點選用)
@@ -1949,7 +1949,7 @@
{ ==============================================================================
方法名稱:DownLoadImage
- 引用相依:SetFtpInfo, IIS_Ftp
+ 引用相依:IIS_Ftp, SetFtpInfo
方法描述:處理影像下載流程。根據案件上傳/下載方式(HTTP 或 FTP),從伺服器下載對應
的 ZIP 檔案並解壓縮至本地案件目錄,供後續異動或補件使用。
============================================================================== }
@@ -2002,7 +2002,7 @@
{ ==============================================================================
方法名稱:Down_Img
- 引用相依:FileExists, Str2Dir, En_DecryptionStr_Base64, dnFile_Get, dnFile
+ 引用相依:En_DecryptionStr_Base64, FileExists, Str2Dir, dnFile, dnFile_Get
方法描述:透過 HTTPS 從伺服器下載案件影像。下載 ZIP 檔案(含 img.zip 與 att.zip)
後執行本地解壓縮,將主影像與附件部署至指定目錄。
============================================================================== }
@@ -2062,7 +2062,7 @@
{ ==============================================================================
方法名稱:GetNoNameCase
- 引用相依:GetNoNameCase, DirectoryExists
+ 引用相依:DirectoryExists, GetNoNameCase
方法描述:在指定的本地路徑中尋找尚未被佔用的「未配號XXXX」目錄名稱。
============================================================================== }
Function TCB_IMGPSScanX.GetNoNameCase(Path:String):String; //取未配號XXXX
@@ -2082,7 +2082,7 @@
{ ==============================================================================
方法名稱:CaseResort
- 引用相依:LoadFromFile, FileExists, RenameFile, SaveToFile, ReSortFileName
+ 引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:對案件檔案進行實體重新排序。依據文件清單(Doc_Inf_List)的順序,對主文件
與次文件進行更名與重新編號,確保檔名序號符合業務邏輯。
============================================================================== }
@@ -2227,7 +2227,7 @@
{ ==============================================================================
方法名稱:CaseResort2Scanlist
- 引用相依:FileExists, LoadFromFile, RenameFile, SaveToFile, ReSortFileName
+ 引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:產生依表單代號排序的影像清單(scanlist.dat),用於上傳。
============================================================================== }
Procedure TCB_IMGPSScanX.CaseResort2Scanlist(Path:String); //案件的檔案重新排序給scanlist(次文件依FormID排)
@@ -2355,7 +2355,7 @@
{ ==============================================================================
方法名稱:DistinctDocinCase
- 引用相依:LoadFromFile, LoadFileGetMD5
+ 引用相依:LoadFileGetMD5, LoadFromFile
方法描述:列出案件目錄下所有具備文件編號與版本的唯一組合。
============================================================================== }
Procedure TCB_IMGPSScanX.DistinctDocinCase(Path:String); //列出案件裡的Docno_版本
@@ -2843,7 +2843,7 @@
{ ==============================================================================
方法名稱:FormIDReplace
- 引用相依:FileExists, LoadFromFile, DirectoryExists, CopyFile, RenameFile, Sav
+ 引用相依:CopyFile, DirectoryExists, FileExists, LoadFromFile, RenameFile, Sav
eToFile
方法描述:將指定文件中的舊表單代碼替換為新代碼。首先決定目標目錄(考慮是否分份數
、補件狀況),若目標目錄不存在則建立。接著將符合舊代碼的檔案複製到新目錄
@@ -3187,7 +3187,7 @@
{ ==============================================================================
方法名稱:WriteResize
- 引用相依:LoadFromFile, FileExists, SaveToFile
+ 引用相依:FileExists, GetTag, LoadFromFile, SaveToFile
方法描述:產生影像縮放記錄檔(Resize.dat)。載入影像後比對原始標記(Tag)中的長寬資
訊與實際 Graphic 的長寬,若有變動則將差異記錄至文字檔中。
============================================================================== }
@@ -3719,7 +3719,7 @@
{ ==============================================================================
方法名稱:ScanGrayCBClick
- 引用相依:ifGray256, ifBlackWhite, ifTrueColor
+ 引用相依:ifBlackWhite, ifGray256, ifTrueColor
方法描述:根據掃瞄勾選框狀態,設定掃瞄色彩模式(灰階、全彩或黑白)。
============================================================================== }
procedure TCB_IMGPSScanX.ScanGrayCBClick(Sender: TObject);
@@ -4180,7 +4180,7 @@
{ ==============================================================================
方法名稱:UseOldCaseLbClick
- 引用相依:FileExists, LoadFromFile, DirectoryExists, CopyFile, SaveToFile
+ 引用相依:CopyFile, DirectoryExists, FileExists, LoadFromFile, SaveToFile
方法描述:處理「使用舊件」功能。開啟 TOldCaseInfoForm 讓使用者選擇舊有案件的文件。
選定後,將舊件影像複製到新案件目錄下,自動產生新序號檔名,建立關聯記錄(
UseCase.dat),並同步更新新案件的文件清單與樹狀統計。
@@ -4689,7 +4689,7 @@
{ ==============================================================================
方法名稱:CheckAvailable
- 引用相依:FileExists, dnFile_Get, dnFile, upFile
+ 引用相依:FileExists, dnFile, dnFile_Get, upFile
方法描述:檢查元件的使用授權。透過 HTTPS 下載掃瞄授權檔,並驗證 MacID、註冊數量與
使用期限。若尚未註冊且仍有額度,則自動進行註冊並上傳新的授權檔至伺服器
。最後在狀態列顯示註冊資訊。
@@ -4811,8 +4811,8 @@
{ ==============================================================================
方法名稱:Case2Mask
- 引用相依:FindPoint, DirectoryExists, _DelTree, Str2Dir, LoadFromFile, FileExi
- sts
+ 引用相依:DirectoryExists, FileExists, FindPoint, LoadFromFile, Str2Dir, _DelT
+ ree
方法描述:產生案件的遮罩影像(用於遮蔽敏感個資)。讀取 Context.dat,針對每張影像尋
找定位點,並依據對應表單的 XML 定義執行區域遮罩,最後存入指定目錄。
============================================================================== }
@@ -5287,7 +5287,7 @@
{ ==============================================================================
方法名稱:MoveImage
- 引用相依:LoadFromFile, RenameFile, SaveToFile, ReSortFileName
+ 引用相依:LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:執行影像頁面的位置移動。先對目錄下所有檔案進行臨時更名(加上 @ 標記),
根據選取狀態重新排列清單順序,最後更新 Context.dat 並重新排序實體檔案
。
@@ -5353,7 +5353,7 @@
{ ==============================================================================
方法名稱:MoveImage_Drag
- 引用相依:LoadFromFile, RenameFile, SaveToFile, ReSortFileName
+ 引用相依:LoadFromFile, ReSortFileName, RenameFile, SaveToFile
方法描述:處理影像拖拉移動。邏輯與 MoveImage 相似,但針對單一來源索引移動至目標
索引的情境進行排列。
============================================================================== }
@@ -5579,7 +5579,7 @@
{ ==============================================================================
方法名稱:view_image_DocNo
- 引用相依:DpiResize, FileExists, LoadFromFile, DirectoryExists
+ 引用相依:DirectoryExists, DpiResize, FileExists, LoadFromFile
方法描述:根據文件代號(DocNo)或表單代號(FormID)顯示影像。函式包含三種模式:顯示
案件內所有影像(ShowAll)、顯示指定文件夾(如 Attach)下的影像,以及顯示指
定文件代號下特定表單的影像。處理過程中會檢查在席狀態(In_WH)、執行影像
diff --git a/reassemble/view/popupMenu.pas b/reassemble/view/popupMenu.pas
index c2c62e0..9611e18 100644
--- a/reassemble/view/popupMenu.pas
+++ b/reassemble/view/popupMenu.pas
@@ -1,7 +1,7 @@
{ ==============================================================================
方法名稱:PM401Click
- 引用相依:GetNoNameCase, Str2Dir, RenameFile, SaveToFile, FileExists, LoadFrom
- File
+ 引用相依:FileExists, GetNoNameCase, LoadFromFile, RenameFile, SaveToFile, Str
+ 2Dir
方法描述:影像列表右鍵選單功能:從指定頁面分出新案。確認使用者選取的分案起點(不
能為第一頁)後,取得新的流水案號並建立目錄。將原案件中該頁碼之後的所有
影像檔案更名並搬移至新案目錄,同步更新原案與新案的 Context.dat 與 Cas
@@ -174,8 +174,8 @@
{ ==============================================================================
方法名稱:PM601Click
- 引用相依:FileExists, LoadFromFile, DirectoryExists, CopyFile, SaveToFile, Del
- eteImageFile, RenameFile, ReSortFileName
+ 引用相依:CopyFile, DeleteImageFile, DirectoryExists, FileExists, LoadFromFile
+ , ReSortFileName, RenameFile, SaveToFile
方法描述:縮圖瀏覽區右鍵選單功能:文件歸類。針對所有被選取(由 Shape 標記)的影像,
開啟 TDocListForm 選擇目標表單。核心邏輯包含:判斷目標文件是否需要區分
份數、自動產生新的文件目錄或沿用既有目錄、根據檔案序號產生新檔名、執行
@@ -339,8 +339,8 @@
{ ==============================================================================
方法名稱:PM602Click
- 引用相依:Str2Dir, FileExists, LoadFromFile, CopyFile, SaveToFile, DeleteImage
- File, ReSortFileName
+ 引用相依:CopyFile, DeleteImageFile, FileExists, LoadFromFile, ReSortFileName,
+ SaveToFile, Str2Dir
方法描述:縮圖瀏覽區右鍵選單功能:歸類至自定義文件。彈出對話框要求使用者輸入新文
件名稱,檢核名稱是否重複後產生新的自定義文件編號。接著將所有選取的影像
複製到新建立的文件目錄下,更新 ContextList並刪除原檔案。最後重新排序並
@@ -428,7 +428,7 @@
{ ==============================================================================
方法名稱:PM604Click
- 引用相依:DeskewImg, SaveToFile, LoadFromFile
+ 引用相依:DeskewImg, LoadFromFile, SaveToFile
方法描述:縮圖瀏覽區右鍵選單功能:自動去偏斜(Deskew)。遍歷所有選取的影像元件,對
其 Graphic 執行 DeskewImg 操作,重新繪製並將結果存回原檔案。
============================================================================== }
@@ -504,7 +504,7 @@
{ ==============================================================================
方法名稱:PM101Click
- 引用相依:_DelTree, DirectoryExists, DeleteDocNoFile
+ 引用相依:DeleteDocNoFile, DirectoryExists, _DelTree
方法描述:處理樹狀結構(TreeView)的右鍵刪除選單。根據選取的節點類型(新掃瞄件、案
件、文件或表單)執行不同範圍的刪除:包含刪除實體目錄、清空影像清單、更新
案件索引及檢核記錄。針對異動模式(ESCAN),若刪除後無影像則會重建空案件
@@ -713,11 +713,11 @@
{ ==============================================================================
方法名稱:PM104Click
- 引用相依:TTiffGraphic, TJpegGraphic, FJpgCompression, DeskewImg, ConvertToBW,
- MpsGetBarcode, Rotate, CheckNeedCrop, CropImg, ifBlackWhite, tcGrou
- p4, ifColor25, ConvertToGray, tcJpeg, ifTrueColor, ifGray256, SaveQu
- ality, FindFirst, LoadFromFile, SaveToFile, DirectoryExists, _DelTre
- e, GetNoNameCase, Str2Dir, FileExists
+ 引用相依:CheckNeedCrop, ConvertToBW, ConvertToGray, CropImg, DeskewImg, Direc
+ toryExists, FJpgCompression, FileExists, FindFirst, GetNoNameCase, L
+ oadFromFile, MpsGetBarcode, Rotate, SaveQuality, SaveToFile, Str2Dir
+ , TJpegGraphic, TTiffGraphic, _DelTree, ifBlackWhite, ifColor25, ifG
+ ray256, ifTrueColor, tcGroup4, tcJpeg
方法描述:處理「匯入影像檔案」右鍵選單。開啟檔案對話框選取 TIF/JPG/PNG 檔,並檢查
檔案大小是否超過限制。核心流程包含:計算總頁數、逐頁載入、執行自動去偏斜
(Deskew)、條碼辨識以判斷 FormID、處理 A3 切圖(左右分割)、將影像轉換為對
@@ -1660,7 +1660,7 @@
{ ==============================================================================
方法名稱:PM508Click
- 引用相依:_DelTree, SaveToFile, ReSortFileName, LoadFromFile, FileExists
+ 引用相依:FileExists, LoadFromFile, ReSortFileName, SaveToFile, _DelTree
方法描述:處理影像區域的「刪除影像」右鍵選單。若案件僅剩一張影像則詢問是否刪除整
個案件目錄。否則,在確認後從影像清單中移除該項目、刪除實體檔案並呼叫 Re
SortFileName 重新排序。最後刷新樹狀統計文字、清空檢核記錄並更新顯示。
diff --git a/reassemble/view/scrollView.pas b/reassemble/view/scrollView.pas
index 3c890df..02e2b9a 100644
--- a/reassemble/view/scrollView.pas
+++ b/reassemble/view/scrollView.pas
@@ -141,7 +141,7 @@
{ ==============================================================================
方法名稱:ISB1ImageMouseUp
- 引用相依:TJpegGraphic, SaveQuality, SaveToFile
+ 引用相依:SaveQuality, SaveToFile, TJpegGraphic
方法描述:影像滑鼠放開事件。處理多種滑鼠模式:在 mmDelete 模式下觸發刪除功能;在
旋轉模式(mmR90等)下儲存旋轉後的影像檔案,並同步更新預覽圖(SelectISB)
與清空檢核記錄。最後針對縮放或拖曳模式更新捲軸位置數據。
@@ -229,7 +229,7 @@
{ ==============================================================================
方法名稱:ImageScrollBox1NewGraphic
- 引用相依:TDibGraphic, ConvertToBW
+ 引用相依:ConvertToBW, TDibGraphic
方法描述:當載入新影像時觸發。將當前 Graphic 內容同步至黑白影像處理元件(ISB_BW)
,若原始影像非黑白格式則執行 ConvertToBW 轉換。
============================================================================== }
diff --git a/reassemble/view/toolBar.pas b/reassemble/view/toolBar.pas
index 3996c08..86962c9 100644
--- a/reassemble/view/toolBar.pas
+++ b/reassemble/view/toolBar.pas
@@ -545,7 +545,7 @@
{ ==============================================================================
方法名稱:SelectScanBtnClick
- 引用相依:SelectScanner, scanner.SelectScanner, Scanner
+ 引用相依:Scanner, SelectScanner, scanner.SelectScanner
方法描述:開啟系統掃瞄器選擇視窗。
============================================================================== }
procedure TCB_IMGPSScanX.SelectScanBtnClick(Sender: TObject);
@@ -737,7 +737,7 @@
{ ==============================================================================
方法名稱:SpeedButton14Click
- 引用相依:Rotate, TJpegGraphic, SaveQuality, LoadFromFile, SaveToFile
+ 引用相依:LoadFromFile, Rotate, SaveQuality, SaveToFile, TJpegGraphic
方法描述:處理工具列按鈕點擊,執行影像逆時針旋轉 90 度(即旋轉 270 度)。程序會重
新載入影像、執行旋轉、根據影像格式(JPG 則設定品質為 30)儲存回原檔案,最
後更新主顯示區與縮圖區,並重新調整縮圖佈局。
@@ -768,7 +768,7 @@
{ ==============================================================================
方法名稱:SpeedButton15Click
- 引用相依:Rotate, TJpegGraphic, SaveQuality, LoadFromFile, SaveToFile
+ 引用相依:LoadFromFile, Rotate, SaveQuality, SaveToFile, TJpegGraphic
方法描述:處理工具列按鈕點擊,執行影像旋轉 180 度。程序重新載入檔案後執行旋轉操
作,並依據格式存檔。完成後同步更新主畫面與預覽圖,確保顯示一致性。
============================================================================== }
@@ -796,7 +796,7 @@
{ ==============================================================================
方法名稱:SpeedButton16Click
- 引用相依:Rotate, TJpegGraphic, SaveQuality, LoadFromFile, SaveToFile
+ 引用相依:LoadFromFile, Rotate, SaveQuality, SaveToFile, TJpegGraphic
方法描述:處理工具列按鈕點擊,執行影像順時針旋轉 90 度。載入影像後執行旋轉並儲存
,針對非黑白影像會設定 JPG 壓縮品質。最後重新繪製相關顯示元件並觸發點
擊事件。
diff --git a/reassemble/view/treeView.pas b/reassemble/view/treeView.pas
index c9d6f17..cc13e2a 100644
--- a/reassemble/view/treeView.pas
+++ b/reassemble/view/treeView.pas
@@ -1,6 +1,6 @@
{ ==============================================================================
方法名稱:DrawDocItem2
- 引用相依:FileExists, LoadFromFile, DirectoryExists
+ 引用相依:DirectoryExists, FileExists, LoadFromFile
方法描述:在樹狀結構中繪製指定案件的文件與表單節點。讀取 CaseDocNo.dat 取得文件
清單,逐一建立文件節點並根據引用狀態設定圖示。接著在文件節點下建立表單
節點,區分制式表單與自定義表單。包含入庫過濾與附件處理,是樹狀 UI 呈現
@@ -506,8 +506,8 @@
{ ==============================================================================
方法名稱:TreeView1DragDrop
- 引用相依:RenameFile, CopyFile, DeleteImageFile, LoadFromFile, SaveToFile, _De
- lTree, ReSortFileName
+ 引用相依:CopyFile, DeleteImageFile, LoadFromFile, ReSortFileName, RenameFile,
+ SaveToFile, _DelTree
方法描述:處理樹狀結構的拖放操作,實現影像的快速歸類或跨案件移動。當使用者將影像
縮圖拖至樹狀節點時,程序會判斷目標層級,執行實際的檔案搬移(Copy/Delete
)與更名,同步更新 Context.dat 索引檔案,並重新整理樹狀顯示與筆數統計。
diff --git a/scripts/dist/CB_IMGPSScanImp.pas.bk.image.csv b/scripts/dist/CB_IMGPSScanImp.pas.bk.image.csv
index 1e80dc4..54f47a9 100644
--- a/scripts/dist/CB_IMGPSScanImp.pas.bk.image.csv
+++ b/scripts/dist/CB_IMGPSScanImp.pas.bk.image.csv
@@ -5,10 +5,12 @@
[V],"Button6Click","CB_IMGPSScanImp.pas.bk","598","Rotate","","BarCodeRotate : Integer; //æ¢ç¢¼è¦è½çè§åº¦"
[V],"Button6Click","CB_IMGPSScanImp.pas.bk","615","FJpgCompression","","FJpgCompression:integer;// 20171211 jpg to tif çå£ç¸®ç"
[V],"GetSiteOMR","CB_IMGPSScanImp.pas.bk","674","GetSiteOMR","","function GetSiteOMR(FileName, Site: String;bt: Integer): Integer;"
+[V],"ImageReSize_FormID","CB_IMGPSScanImp.pas.bk","742","ImageResize","","Procedure ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾"
[V],"ImageReSize_FormID","CB_IMGPSScanImp.pas.bk","742","ImageReSize_FormID","","Procedure ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾"
+[V],"ImageReSize_tmp","CB_IMGPSScanImp.pas.bk","743","ImageResize","","Procedure ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)"
[V],"ImageReSize_tmp","CB_IMGPSScanImp.pas.bk","743","ImageReSize_tmp","","Procedure ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)"
-[V],"CheckNeedCrop","CB_IMGPSScanImp.pas.bk","804","TDibGraphic","","Function CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å"
[V],"CheckNeedCrop","CB_IMGPSScanImp.pas.bk","804","CheckNeedCrop","","Function CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å"
+[V],"CheckNeedCrop","CB_IMGPSScanImp.pas.bk","804","TDibGraphic","","Function CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å"
[V],"Initialize","CB_IMGPSScanImp.pas.bk","1044","TDibGraphic","","EnPrint, { for TEnvisionPrintMode, TDibGraphicPrinter }"
[V],"TCB_IMGPSScanX.ISB1ImageMouseUp","CB_IMGPSScanImp.pas.bk","1505","TJpegGraphic","","TJpegGraphic(TImageScrollBox(Sender).Graphic).SaveQuality := 30;"
[V],"TCB_IMGPSScanX.ISB1ImageMouseUp","CB_IMGPSScanImp.pas.bk","1505","SaveQuality","","TJpegGraphic(TImageScrollBox(Sender).Graphic).SaveQuality := 30;"
@@ -27,8 +29,8 @@
[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3005","ifColor25","","else if iGraphic.ImageFormat= ifColor256 then"
[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3008","ConvertToGray","","ConverttoGray(iGraphic);"
[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3009","tcJpeg","","iGraphic.Compression:=tcJPEG;"
-[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3012","ifTrueColor","","else if (iGraphic.ImageFormat = ifTrueColor) or (iGraphic.ImageFormat = ifGray256) then"
[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3012","ifGray256","","else if (iGraphic.ImageFormat = ifTrueColor) or (iGraphic.ImageFormat = ifGray256) then"
+[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3012","ifTrueColor","","else if (iGraphic.ImageFormat = ifTrueColor) or (iGraphic.ImageFormat = ifGray256) then"
[V],"TCB_IMGPSScanX.PM104Click","CB_IMGPSScanImp.pas.bk","3050","SaveQuality","","JpgGr.SaveQuality := 30;"
[V],"TCB_IMGPSScanX.PM301Click","CB_IMGPSScanImp.pas.bk","3475","ifBlackWhite","","ScanColor := ifBlackWhite;"
[V],"TCB_IMGPSScanX.PM302Click","CB_IMGPSScanImp.pas.bk","3483","ifGray256","","ScanColor := ifGray256;"
@@ -62,14 +64,18 @@
[V],"TCB_IMGPSScanX.GetSiteOMR","CB_IMGPSScanImp.pas.bk","5222","Get_OMR","","result := Get_OMR(ISB_BW.Graphic,OMRRect);"
[V],"TCB_IMGPSScanX.GetDefScanIni","CB_IMGPSScanImp.pas.bk","5366","Rotate","","Else if GetSQLData(WORK_INF_List,'PARA_NO',i) = 'SCAN_ROTATE_MODE' Then //æçææè½è§åº¦"
[V],"TCB_IMGPSScanX.GetDefScanIni","CB_IMGPSScanImp.pas.bk","5462","FJpgCompression","","FJpgCompression := StrToInt(PARA_CONTENT);"
+[V],"TCB_IMGPSScanX.CaseReSize","CB_IMGPSScanImp.pas.bk","6336","ImageResize","","ImageReSize_FormID(CaseID,FileName); //ä¾ååå®ä½é»å縮æ¾"
[V],"TCB_IMGPSScanX.CaseReSize","CB_IMGPSScanImp.pas.bk","6336","ImageReSize_FormID","","ImageReSize_FormID(CaseID,FileName); //ä¾ååå®ä½é»å縮æ¾"
+[V],"TCB_IMGPSScanX.ImageReSize_FormID","CB_IMGPSScanImp.pas.bk","6343","ImageResize","","Procedure TCB_IMGPSScanX.ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾"
[V],"TCB_IMGPSScanX.ImageReSize_FormID","CB_IMGPSScanImp.pas.bk","6343","ImageReSize_FormID","","Procedure TCB_IMGPSScanX.ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾"
[V],"TCB_IMGPSScanX.ImageReSize_FormID","CB_IMGPSScanImp.pas.bk","6376","FindPoint","","//FindPoint(ImageScrollBox1.Graphic,UpLPoint,UpRPoint,DownLPoint,NowW,NowH);"
[V],"TCB_IMGPSScanX.ImageReSize_FormID","CB_IMGPSScanImp.pas.bk","6379","CheckSize","","SizeStr := CheckSize(ISB_BW,UpLPoint,UpRPoint,DownLPoint,DW,DH);"
+[V],"TCB_IMGPSScanX.ImageReSize_tmp","CB_IMGPSScanImp.pas.bk","6421","ImageResize","","Procedure TCB_IMGPSScanX.ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)"
[V],"TCB_IMGPSScanX.ImageReSize_tmp","CB_IMGPSScanImp.pas.bk","6421","ImageReSize_tmp","","Procedure TCB_IMGPSScanX.ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)"
[V],"TCB_IMGPSScanX.ImageReSize_tmp","CB_IMGPSScanImp.pas.bk","6437","CheckSize","","SizeStr := CheckSize(ImageScrollBox1,UpLPoint,UpRPoint,DownLPoint,DW,DH);"
[V],"TCB_IMGPSScanX.ImageScrollBox1NewGraphic","CB_IMGPSScanImp.pas.bk","6447","TDibGraphic","","procedure TCB_IMGPSScanX.ImageScrollBox1NewGraphic(const Graphic: TDibGraphic);"
[V],"TCB_IMGPSScanX.ImageScrollBox1NewGraphic","CB_IMGPSScanImp.pas.bk","6453","ConvertToBW","","ConvertToBW(ISB_BW.Graphic);"
+[V],"TCB_IMGPSScanX.WriteResize","CB_IMGPSScanImp.pas.bk","8026","GetTag","","TagTxt := GetTag(ImgName);"
[V],"TCB_IMGPSScanX.ScanGrayCBClick","CB_IMGPSScanImp.pas.bk","8573","ifGray256","","ScanColor:=ifGray256;"
[V],"TCB_IMGPSScanX.ScanGrayCBClick","CB_IMGPSScanImp.pas.bk","8579","ifBlackWhite","","ScanColor := ifBlackWhite;"
[V],"TCB_IMGPSScanX.ScanGrayCBClick","CB_IMGPSScanImp.pas.bk","8591","ifTrueColor","","ScanColor := ifTrueColor ;"
@@ -78,11 +84,12 @@
[V],"TCB_IMGPSScanX.initParameter","CB_IMGPSScanImp.pas.bk","9301","ifTrueColor","","ScanColor := ifTrueColor ;"
[V],"TCB_IMGPSScanX.SmoothCBClick","CB_IMGPSScanImp.pas.bk","9927","Image_Smooth","","Image_Smooth(ISB1.Graphic);"
[V],"TCB_IMGPSScanX.Case2Mask","CB_IMGPSScanImp.pas.bk","9962","FindPoint","","//ParserPoint(CropMpsV.FindPoint(Anchor));"
-[V],"TCB_IMGPSScanX.CheckNeedCrop","CB_IMGPSScanImp.pas.bk","9996","TDibGraphic","","Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å"
[V],"TCB_IMGPSScanX.CheckNeedCrop","CB_IMGPSScanImp.pas.bk","9996","CheckNeedCrop","","Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å"
+[V],"TCB_IMGPSScanX.CheckNeedCrop","CB_IMGPSScanImp.pas.bk","9996","TDibGraphic","","Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å"
[V],"TCB_IMGPSScanX.PrintImg","CB_IMGPSScanImp.pas.bk","10223","TDibGraphic","","GraphicPrinter : TDibGraphicPrinter;"
[V],"PrintWithManualPrintJob","CB_IMGPSScanImp.pas.bk","10241","TDibGraphic","","property of the TDibGraphicPrinter object is used to specify the"
[V],"PrintWithAutoPrintJob","CB_IMGPSScanImp.pas.bk","10274","TDibGraphic","","GraphicPrinter := TDibGraphicPrinter.Create;"
+[V],"TCB_IMGPSScanX.OMRCheckCase","CB_IMGPSScanImp.pas.bk","12510","ImageResize","","ImageReSize_FormID(CaseID,OMRFile);"
[V],"TCB_IMGPSScanX.OMRCheckCase","CB_IMGPSScanImp.pas.bk","12510","ImageReSize_FormID","","ImageReSize_FormID(CaseID,OMRFile);"
[V],"TCB_IMGPSScanX.OMRCheckCase","CB_IMGPSScanImp.pas.bk","12545","GetSiteOMR","","//Showmessage(ColCName +','+ inttostr(OMRMpsV1.GetSiteOMR(ImageSavePath+CaseID+'\upload\'+OMRFile,Site))+','+inttostr(Pixel + SafePixel));"
[V],"TCB_IMGPSScanX.OMRCheckCase","CB_IMGPSScanImp.pas.bk","12548","FindPoint","","//FindPoint(ISB_BW.Graphic,UpLPoint,UpRPoint,DownLPoint,ANCHOR);"
diff --git a/scripts/dist/ErrList.pas.image.csv b/scripts/dist/ErrList.pas.image.csv
index 793ade6..6fc0939 100644
--- a/scripts/dist/ErrList.pas.image.csv
+++ b/scripts/dist/ErrList.pas.image.csv
@@ -1,5 +1,8 @@
[ ],方法名,所在檔名,行號,引用了什麼相依,方法描述(請手動填寫),原始程式碼片段
[V],"ImageScrollBox1NewGraphic","ErrList.pas","109","TDibGraphic","","procedure ImageScrollBox1NewGraphic(const Graphic: TDibGraphic);"
[V],"TErrlistForm.GetOMRErrini","ErrList.pas","487","FindPoint","","//FindPoint(ImageScrollBox1.Graphic,UpLPoint,UpRPoint,DownLPoint,'NONE');"
+[V],"TErrlistForm.GetOMRErrini","ErrList.pas","493","ImageResize","","ImageResize(ImageScrollBox1.Graphic,ISB_BW.Graphic.Width,ISB_BW.Graphic.Height);"
+[V],"TErrlistForm.ShowOMRErr","ErrList.pas","549","ShowKeyinRect","","//ShowKeyinRect(ImageScrollBox1,iRect);"
[V],"TErrlistForm.ImageScrollBox1NewGraphic","ErrList.pas","553","TDibGraphic","","procedure TErrlistForm.ImageScrollBox1NewGraphic(const Graphic: TDibGraphic);"
-[V],"TErrlistForm.ImageScrollBox1NewGraphic","ErrList.pas","559","ConvertToBW","","ConvertToBW(ISB_BW.Graphic);"
\ No newline at end of file
+[V],"TErrlistForm.ImageScrollBox1NewGraphic","ErrList.pas","559","ConvertToBW","","ConvertToBW(ISB_BW.Graphic);"
+[V],"TErrlistForm.ShowRelaOMRErr","ErrList.pas","586","ShowKeyinRect","","//ShowKeyinRect(ImageScrollBox2,iRect);"
\ No newline at end of file
diff --git a/scripts/dist/deps.all.csv b/scripts/dist/deps.all.csv
index c0ec7ca..383a538 100644
--- a/scripts/dist/deps.all.csv
+++ b/scripts/dist/deps.all.csv
@@ -5,10 +5,12 @@
[V],Button6Click,CB_IMGPSScanImp.pas.bk,598,Rotate,,BarCodeRotate : Integer; //æ¢ç¢¼è¦è½çè§åº¦
[V],Button6Click,CB_IMGPSScanImp.pas.bk,615,FJpgCompression,,FJpgCompression:integer;// 20171211 jpg to tif çå£ç¸®ç
[V],GetSiteOMR,CB_IMGPSScanImp.pas.bk,674,GetSiteOMR,,function GetSiteOMR(FileName, Site: String;bt: Integer): Integer;
+[V],ImageReSize_FormID,CB_IMGPSScanImp.pas.bk,742,ImageResize,,Procedure ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾
[V],ImageReSize_FormID,CB_IMGPSScanImp.pas.bk,742,ImageReSize_FormID,,Procedure ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾
+[V],ImageReSize_tmp,CB_IMGPSScanImp.pas.bk,743,ImageResize,,Procedure ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)
[V],ImageReSize_tmp,CB_IMGPSScanImp.pas.bk,743,ImageReSize_tmp,,Procedure ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)
-[V],CheckNeedCrop,CB_IMGPSScanImp.pas.bk,804,TDibGraphic,,Function CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å
[V],CheckNeedCrop,CB_IMGPSScanImp.pas.bk,804,CheckNeedCrop,,Function CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å
+[V],CheckNeedCrop,CB_IMGPSScanImp.pas.bk,804,TDibGraphic,,Function CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å
[V],Initialize,CB_IMGPSScanImp.pas.bk,1044,TDibGraphic,,EnPrint, { for TEnvisionPrintMode, TDibGraphicPrinter }
[V],TCB_IMGPSScanX.ISB1ImageMouseUp,CB_IMGPSScanImp.pas.bk,1505,TJpegGraphic,,TJpegGraphic(TImageScrollBox(Sender).Graphic).SaveQuality := 30;
[V],TCB_IMGPSScanX.ISB1ImageMouseUp,CB_IMGPSScanImp.pas.bk,1505,SaveQuality,,TJpegGraphic(TImageScrollBox(Sender).Graphic).SaveQuality := 30;
@@ -27,8 +29,8 @@
[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3005,ifColor25,,else if iGraphic.ImageFormat= ifColor256 then
[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3008,ConvertToGray,,ConverttoGray(iGraphic);
[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3009,tcJpeg,,iGraphic.Compression:=tcJPEG;
-[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3012,ifTrueColor,,else if (iGraphic.ImageFormat = ifTrueColor) or (iGraphic.ImageFormat = ifGray256) then
[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3012,ifGray256,,else if (iGraphic.ImageFormat = ifTrueColor) or (iGraphic.ImageFormat = ifGray256) then
+[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3012,ifTrueColor,,else if (iGraphic.ImageFormat = ifTrueColor) or (iGraphic.ImageFormat = ifGray256) then
[V],TCB_IMGPSScanX.PM104Click,CB_IMGPSScanImp.pas.bk,3050,SaveQuality,,JpgGr.SaveQuality := 30;
[V],TCB_IMGPSScanX.PM301Click,CB_IMGPSScanImp.pas.bk,3475,ifBlackWhite,,ScanColor := ifBlackWhite;
[V],TCB_IMGPSScanX.PM302Click,CB_IMGPSScanImp.pas.bk,3483,ifGray256,,ScanColor := ifGray256;
@@ -62,14 +64,18 @@
[V],TCB_IMGPSScanX.GetSiteOMR,CB_IMGPSScanImp.pas.bk,5222,Get_OMR,,result := Get_OMR(ISB_BW.Graphic,OMRRect);
[V],TCB_IMGPSScanX.GetDefScanIni,CB_IMGPSScanImp.pas.bk,5366,Rotate,,Else if GetSQLData(WORK_INF_List,'PARA_NO',i) = 'SCAN_ROTATE_MODE' Then //æçææè½è§åº¦
[V],TCB_IMGPSScanX.GetDefScanIni,CB_IMGPSScanImp.pas.bk,5462,FJpgCompression,,FJpgCompression := StrToInt(PARA_CONTENT);
+[V],TCB_IMGPSScanX.CaseReSize,CB_IMGPSScanImp.pas.bk,6336,ImageResize,,ImageReSize_FormID(CaseID,FileName); //ä¾ååå®ä½é»å縮æ¾
[V],TCB_IMGPSScanX.CaseReSize,CB_IMGPSScanImp.pas.bk,6336,ImageReSize_FormID,,ImageReSize_FormID(CaseID,FileName); //ä¾ååå®ä½é»å縮æ¾
+[V],TCB_IMGPSScanX.ImageReSize_FormID,CB_IMGPSScanImp.pas.bk,6343,ImageResize,,Procedure TCB_IMGPSScanX.ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾
[V],TCB_IMGPSScanX.ImageReSize_FormID,CB_IMGPSScanImp.pas.bk,6343,ImageReSize_FormID,,Procedure TCB_IMGPSScanX.ImageReSize_FormID(CaseID,FileName:String); //ä¾ååå®ä½é»å縮æ¾
[V],TCB_IMGPSScanX.ImageReSize_FormID,CB_IMGPSScanImp.pas.bk,6376,FindPoint,,//FindPoint(ImageScrollBox1.Graphic,UpLPoint,UpRPoint,DownLPoint,NowW,NowH);
[V],TCB_IMGPSScanX.ImageReSize_FormID,CB_IMGPSScanImp.pas.bk,6379,CheckSize,,SizeStr := CheckSize(ISB_BW,UpLPoint,UpRPoint,DownLPoint,DW,DH);
+[V],TCB_IMGPSScanX.ImageReSize_tmp,CB_IMGPSScanImp.pas.bk,6421,ImageResize,,Procedure TCB_IMGPSScanX.ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)
[V],TCB_IMGPSScanX.ImageReSize_tmp,CB_IMGPSScanImp.pas.bk,6421,ImageReSize_tmp,,Procedure TCB_IMGPSScanX.ImageReSize_tmp(FormID,FileName:String); //ä¾ååå®ä½é»å縮æ¾(æ«åæª)
[V],TCB_IMGPSScanX.ImageReSize_tmp,CB_IMGPSScanImp.pas.bk,6437,CheckSize,,SizeStr := CheckSize(ImageScrollBox1,UpLPoint,UpRPoint,DownLPoint,DW,DH);
[V],TCB_IMGPSScanX.ImageScrollBox1NewGraphic,CB_IMGPSScanImp.pas.bk,6447,TDibGraphic,,procedure TCB_IMGPSScanX.ImageScrollBox1NewGraphic(const Graphic: TDibGraphic);
[V],TCB_IMGPSScanX.ImageScrollBox1NewGraphic,CB_IMGPSScanImp.pas.bk,6453,ConvertToBW,,ConvertToBW(ISB_BW.Graphic);
+[V],TCB_IMGPSScanX.WriteResize,CB_IMGPSScanImp.pas.bk,8026,GetTag,,TagTxt := GetTag(ImgName);
[V],TCB_IMGPSScanX.ScanGrayCBClick,CB_IMGPSScanImp.pas.bk,8573,ifGray256,,ScanColor:=ifGray256;
[V],TCB_IMGPSScanX.ScanGrayCBClick,CB_IMGPSScanImp.pas.bk,8579,ifBlackWhite,,ScanColor := ifBlackWhite;
[V],TCB_IMGPSScanX.ScanGrayCBClick,CB_IMGPSScanImp.pas.bk,8591,ifTrueColor,,ScanColor := ifTrueColor ;
@@ -78,11 +84,12 @@
[V],TCB_IMGPSScanX.initParameter,CB_IMGPSScanImp.pas.bk,9301,ifTrueColor,,ScanColor := ifTrueColor ;
[V],TCB_IMGPSScanX.SmoothCBClick,CB_IMGPSScanImp.pas.bk,9927,Image_Smooth,,Image_Smooth(ISB1.Graphic);
[V],TCB_IMGPSScanX.Case2Mask,CB_IMGPSScanImp.pas.bk,9962,FindPoint,,//ParserPoint(CropMpsV.FindPoint(Anchor));
-[V],TCB_IMGPSScanX.CheckNeedCrop,CB_IMGPSScanImp.pas.bk,9996,TDibGraphic,,Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å
[V],TCB_IMGPSScanX.CheckNeedCrop,CB_IMGPSScanImp.pas.bk,9996,CheckNeedCrop,,Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å
+[V],TCB_IMGPSScanX.CheckNeedCrop,CB_IMGPSScanImp.pas.bk,9996,TDibGraphic,,Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //æ¯å¦æ¯A3è¦åå½±å
[V],TCB_IMGPSScanX.PrintImg,CB_IMGPSScanImp.pas.bk,10223,TDibGraphic,,GraphicPrinter : TDibGraphicPrinter;
[V],PrintWithManualPrintJob,CB_IMGPSScanImp.pas.bk,10241,TDibGraphic,,property of the TDibGraphicPrinter object is used to specify the
[V],PrintWithAutoPrintJob,CB_IMGPSScanImp.pas.bk,10274,TDibGraphic,,GraphicPrinter := TDibGraphicPrinter.Create;
+[V],TCB_IMGPSScanX.OMRCheckCase,CB_IMGPSScanImp.pas.bk,12510,ImageResize,,ImageReSize_FormID(CaseID,OMRFile);
[V],TCB_IMGPSScanX.OMRCheckCase,CB_IMGPSScanImp.pas.bk,12510,ImageReSize_FormID,,ImageReSize_FormID(CaseID,OMRFile);
[V],TCB_IMGPSScanX.OMRCheckCase,CB_IMGPSScanImp.pas.bk,12545,GetSiteOMR,,//Showmessage(ColCName +','+ inttostr(OMRMpsV1.GetSiteOMR(ImageSavePath+CaseID+'\upload\'+OMRFile,Site))+','+inttostr(Pixel + SafePixel));
[V],TCB_IMGPSScanX.OMRCheckCase,CB_IMGPSScanImp.pas.bk,12548,FindPoint,,//FindPoint(ISB_BW.Graphic,UpLPoint,UpRPoint,DownLPoint,ANCHOR);
@@ -103,8 +110,11 @@
[V],TCB_IMGPSScanX.Set_scancolor,CB_IMGPSScanImp.pas.bk,16372,ifTrueColor,,ScanColor := ifTrueColor ;
[V],ImageScrollBox1NewGraphic,ErrList.pas,109,TDibGraphic,,procedure ImageScrollBox1NewGraphic(const Graphic: TDibGraphic);
[V],TErrlistForm.GetOMRErrini,ErrList.pas,487,FindPoint,,//FindPoint(ImageScrollBox1.Graphic,UpLPoint,UpRPoint,DownLPoint,'NONE');
+[V],TErrlistForm.GetOMRErrini,ErrList.pas,493,ImageResize,,ImageResize(ImageScrollBox1.Graphic,ISB_BW.Graphic.Width,ISB_BW.Graphic.Height);
+[V],TErrlistForm.ShowOMRErr,ErrList.pas,549,ShowKeyinRect,,//ShowKeyinRect(ImageScrollBox1,iRect);
[V],TErrlistForm.ImageScrollBox1NewGraphic,ErrList.pas,553,TDibGraphic,,procedure TErrlistForm.ImageScrollBox1NewGraphic(const Graphic: TDibGraphic);
[V],TErrlistForm.ImageScrollBox1NewGraphic,ErrList.pas,559,ConvertToBW,,ConvertToBW(ISB_BW.Graphic);
+[V],TErrlistForm.ShowRelaOMRErr,ErrList.pas,586,ShowKeyinRect,,//ShowKeyinRect(ImageScrollBox2,iRect);
[V],TOldCaseInfoForm.ShowImage,OldCaseInfo.pas,333,DpiResize,,DpiResize(ISB.Graphic,36,False);
[V],ReSortFileName_New,CB_IMGPSScanImp.pas.bk,726,ReSortFileName,,Procedure ReSortFileName_New(Path:String); //æªåéæ°æåº
[V],ReSortFileName,CB_IMGPSScanImp.pas.bk,727,ReSortFileName,,Procedure ReSortFileName(Path:String); //æªåéæ°æåº
diff --git a/scripts/list_image_dependencies.js b/scripts/list_image_dependencies.js
index ee661ac..d43faed 100644
--- a/scripts/list_image_dependencies.js
+++ b/scripts/list_image_dependencies.js
@@ -12,49 +12,67 @@
const exclusions = Array.from(new Set([
'ScanRotate',
'ImageFormat <> ifBlackWhite',
-
+
])).join('|')
// 您提供的關鍵字 (以 | 分隔)
const keywordsStr = Array.from(new Set([
- 'TTiffGraphic',
- 'TDibGraphic',
- 'DeskewImg',
- 'Rotate',
+ 'BrightnessImg', // iis_image_process
+ 'CheckNeedCrop',
+ 'CheckSize',
+ 'CleanupBorder',
+ 'Color2BW_RTS', // iis_image_process
+ 'ConvertToBW',
+ 'ConvertToGray',
+ 'CreateReportImg_JSON', // iis_image_process
+ 'CreateStamp', // iis_image_process
'CropImg',
+ 'DeskewImg',
+ 'DpiResize',
+ 'FilterColor', // iis_image_process
+ 'FindBlackPoint', // iis_image_process
+ 'FindPoint',
+ 'GetSiteOMR',
+ 'GetBlackSpots', // iis_image_process
+ 'GetSelectRect2String', // iis_image_process
+ 'GetTag', //
+ 'Get_OMR',
+ 'Gray2BW_RTS', // iis_image_process
+ 'ImageResize', // iis_image_process
+ 'ImageProcessor.anchorAnalyzer',
+ 'ImageProcessor.barcodeRecognizer',
+ 'ImageProcessor.converter',
+ 'ImageProcessor.transformer',
'ImageReSize_FormID',
'ImageReSize_tmp',
- 'CheckNeedCrop',
- 'ImageProcessor.transformer',
- 'ConvertToBW',
- 'ConvertToGray',
'Image_Smooth',
- 'NegativeImg',
- 'CleanupBorder',
- 'ImageProcessor.converter',
+ 'JpgReSize_Exif', // iis
'MpsGetBarcode',
- 'Get_OMR',
- 'ImageProcessor.barcodeRecognizer',
- 'FindPoint',
- 'CheckSize',
- 'GetSiteOMR',
- 'ImageProcessor.anchorAnalyzer',
+ 'NegativeImg',
+ 'PrintBarcode', // iis
+ 'Rotate',
+ 'SetTag', // iis
+ 'ShowKeyinRect', // iis
+ 'TDibGraphic',
'TJpegGraphic',
- 'DpiResize',
+ 'TNBCleanupBorderTransform', // iis
+ 'TTiffGraphic',
+ 'TWatermarkTransform', // iis
+ 'Watermark1_Hong', // iis
// 以下可省
- 'SaveQuality',
- 'FJpgCompression',
- 'ifTrueColor',
- 'ifGray256',
+ 'CleanupBorder',
'ConvertToBW',
'ConvertToGray',
+ 'FJpgCompression',
'Image_Smooth',
'NegativeImg',
- 'CleanupBorder',
+ 'SaveQuality',
'ifBlackWhite',
+ 'ifColor25',
+ 'ifGray256',
+ 'ifTrueColor',
'tcGroup4',
- 'tcPackBits',
'tcJpeg',
- 'ifColor25'
+ 'tcPackBits',
])).join('|')
// 執行腳本 (請確認您的目標檔案名稱,預設為 CB_IMGPSScanImp.pas)
const targetFiles = [
diff --git a/scripts/scanimpl_annalysis_json_deps.js b/scripts/scanimpl_annalysis_json_deps.js
new file mode 100644
index 0000000..2f68dd9
--- /dev/null
+++ b/scripts/scanimpl_annalysis_json_deps.js
@@ -0,0 +1,90 @@
+const fs = require('fs');
+const path = require('path');
+
+const csvPath = 'scripts/dist/deps.all.csv';
+const jsonDir = 'doc/curtis/prompt/scanimpl_analysis';
+const modules = [
+ 'ScannerController',
+ 'BusinessLogic',
+ 'ImageProcessor',
+ 'TransportManager',
+ 'UIView'
+];
+
+function parseCSV(csv) {
+ const lines = csv.split('\n');
+ const depsMap = {};
+
+ // Skip header
+ for (let i = 1; i < lines.length; i++) {
+ const line = lines[i].trim();
+ if (!line) continue;
+
+ // Simple CSV parser (not handling quoted commas as there shouldn't be any in this specific CSV structure)
+ const parts = line.split(',');
+ if (parts.length < 5) continue;
+
+ const methodName = parts[1].trim();
+ const dep = parts[4].trim();
+
+ if (methodName && dep) {
+ if (!depsMap[methodName]) {
+ depsMap[methodName] = new Set();
+ }
+ depsMap[methodName].add(dep);
+ }
+ }
+
+ // Convert sets to sorted arrays
+ const result = {};
+ for (const name in depsMap) {
+ result[name] = Array.from(depsMap[name]).sort();
+ }
+ return result;
+}
+
+function updateJSONs() {
+ const csvContent = fs.readFileSync(csvPath, 'utf8');
+ const depsMap = parseCSV(csvContent);
+
+ modules.forEach(mod => {
+ const filePath = path.join(jsonDir, `scanimpl_annalysis.${mod}.json`);
+ if (!fs.existsSync(filePath)) {
+ console.log(`File not found: ${filePath}`);
+ return;
+ }
+
+ let methods = JSON.parse(fs.readFileSync(filePath, 'utf8'));
+ let updatedCount = 0;
+
+ methods = methods.map(method => {
+ // Find matching methodName in depsMap
+ // matcher example: "function TCB_IMGPSScanX.GetSiteOMR("
+ // methodName example: "GetSiteOMR"
+
+ const foundDeps = new Set();
+
+ for (const methodName in depsMap) {
+ // Use regex to match exact method name within the matcher string
+ const regex = new RegExp(`\\b${methodName}\\b`);
+ if (regex.test(method.matcher)) {
+ depsMap[methodName].forEach(d => foundDeps.add(d));
+ }
+ }
+
+ if (foundDeps.size > 0) {
+ method.deps = Array.from(foundDeps).sort();
+ updatedCount++;
+ } else {
+ // Keep existing deps if any, or initialize to empty array if required
+ if (!method.deps) method.deps = [];
+ }
+ return method;
+ });
+
+ fs.writeFileSync(filePath, JSON.stringify(methods, null, 2), 'utf8');
+ console.log(`Updated ${updatedCount} methods in ${filePath}`);
+ });
+}
+
+updateJSONs();
--
Gitblit v1.8.0