feat: add OCR language extension configuration and documentation
- Introduced `compose.ocr-languages.yml` for installing additional Tesseract OCR language packs during container startup. - Updated documentation to include new OCR language extension options and usage scenarios. - Enhanced existing documentation with references to the new OCR language extension guide. - Improved test coverage for the deark converter and formats, ensuring accurate format handling and error management. - Refactored code to streamline file system operations and improve readability.
This commit is contained in:
parent
737e925ac7
commit
a4489f4945
11 changed files with 766 additions and 90 deletions
345
docs/Docker組合配置/OCR語言擴展.md
Normal file
345
docs/Docker組合配置/OCR語言擴展.md
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
# OCR 語言擴展指南
|
||||
|
||||
ConvertX-CN 預設內建 7 種 OCR 語言(+ 自動多語言模式),但你可以透過多種方式擴展支援更多語言。
|
||||
|
||||
---
|
||||
|
||||
## 內建語言
|
||||
|
||||
以下語言已預先安裝,無需額外配置:
|
||||
|
||||
| 語言 | Tesseract 代碼 | UI 格式代碼 |
|
||||
| -------- | -------------- | ----------- |
|
||||
| 英文 | `eng` | `pdf-en` |
|
||||
| 繁體中文 | `chi_tra` | `pdf-zh-TW` |
|
||||
| 簡體中文 | `chi_sim` | `pdf-zh` |
|
||||
| 日文 | `jpn` | `pdf-ja` |
|
||||
| 韓文 | `kor` | `pdf-ko` |
|
||||
| 德文 | `deu` | `pdf-de` |
|
||||
| 法文 | `fra` | `pdf-fr` |
|
||||
|
||||
另外還有 `pdf-ocr` 自動多語言模式,會同時使用所有已安裝的語言包。
|
||||
|
||||
---
|
||||
|
||||
## 擴展方法比較
|
||||
|
||||
| 方法 | 優點 | 缺點 | 適用場景 |
|
||||
| --------------------------- | ---------------------- | ------------------ | -------------- |
|
||||
| **方法一:compose.yaml** | 簡單、無需建立額外檔案 | 每次啟動需重新安裝 | 測試、臨時使用 |
|
||||
| **方法二:掛載語言包** | 離線可用、啟動快 | 需手動下載檔案 | 離線環境 |
|
||||
| **方法三:自訂 Dockerfile** | 一次安裝、啟動最快 | 需要建立自訂 image | 生產環境 |
|
||||
|
||||
---
|
||||
|
||||
## 方法一:透過 compose.yaml 安裝
|
||||
|
||||
### 完整範例
|
||||
|
||||
```yaml
|
||||
# compose.yaml
|
||||
services:
|
||||
convertx:
|
||||
image: ghcr.io/cysk003/convertx-cn:latest
|
||||
container_name: convertx-cn
|
||||
restart: unless-stopped
|
||||
|
||||
# 使用自訂 entrypoint 安裝額外語言包
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
echo "📦 正在安裝額外 OCR 語言包..."
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr-spa \
|
||||
tesseract-ocr-ita \
|
||||
tesseract-ocr-por \
|
||||
tesseract-ocr-rus \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
echo "✅ 語言包安裝完成"
|
||||
echo "🚀 啟動 ConvertX..."
|
||||
exec bun run start
|
||||
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
|
||||
environment:
|
||||
- TZ=Asia/Taipei
|
||||
- JWT_SECRET=請改成你自己的長隨機字串-至少32個字元
|
||||
- ACCOUNT_REGISTRATION=true
|
||||
- HTTP_ALLOWED=true
|
||||
- ALLOW_UNAUTHENTICATED=false
|
||||
- AUTO_DELETE_EVERY_N_HOURS=24
|
||||
```
|
||||
|
||||
### 說明
|
||||
|
||||
1. `entrypoint` 和 `command` 覆蓋了原本的啟動命令
|
||||
2. 在啟動應用前先執行 `apt-get install` 安裝語言包
|
||||
3. `exec bun run start` 確保應用正確啟動並接收信號
|
||||
|
||||
### 注意事項
|
||||
|
||||
> ⚠️ **每次容器重啟都會重新安裝語言包**,首次啟動可能需要 1-2 分鐘。
|
||||
|
||||
> 💡 如果需要更快的啟動速度,請使用方法二或方法三。
|
||||
|
||||
---
|
||||
|
||||
## 方法二:掛載語言包(推薦離線環境)
|
||||
|
||||
### 步驟 1:下載語言包
|
||||
|
||||
```bash
|
||||
# 建立 tessdata 目錄
|
||||
mkdir -p tessdata
|
||||
cd tessdata
|
||||
|
||||
# 下載需要的語言包
|
||||
# 高精度版(推薦,檔案較大)
|
||||
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/spa.traineddata # 西班牙文
|
||||
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/ita.traineddata # 義大利文
|
||||
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/por.traineddata # 葡萄牙文
|
||||
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/rus.traineddata # 俄文
|
||||
|
||||
# 或使用標準版(檔案較小,速度較快)
|
||||
# wget https://github.com/tesseract-ocr/tessdata/raw/main/spa.traineddata
|
||||
```
|
||||
|
||||
### 步驟 2:配置 compose.yaml
|
||||
|
||||
```yaml
|
||||
# compose.yaml
|
||||
services:
|
||||
convertx:
|
||||
image: ghcr.io/cysk003/convertx-cn:latest
|
||||
container_name: convertx-cn
|
||||
restart: unless-stopped
|
||||
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
# 掛載語言包目錄
|
||||
- ./tessdata:/usr/share/tesseract-ocr/5/tessdata:ro
|
||||
|
||||
environment:
|
||||
- TZ=Asia/Taipei
|
||||
- JWT_SECRET=請改成你自己的長隨機字串-至少32個字元
|
||||
```
|
||||
|
||||
### 目錄結構
|
||||
|
||||
```
|
||||
your-project/
|
||||
├── compose.yaml
|
||||
├── data/
|
||||
└── tessdata/
|
||||
├── spa.traineddata
|
||||
├── ita.traineddata
|
||||
├── por.traineddata
|
||||
└── rus.traineddata
|
||||
```
|
||||
|
||||
### 語言包下載來源
|
||||
|
||||
| 版本 | 說明 | 下載位置 |
|
||||
| -------- | -------------------- | ---------------------------------------------- |
|
||||
| 高精度版 | 辨識準確度最高 | https://github.com/tesseract-ocr/tessdata_best |
|
||||
| 標準版 | 平衡準確度與速度 | https://github.com/tesseract-ocr/tessdata |
|
||||
| 快速版 | 速度最快,準確度較低 | https://github.com/tesseract-ocr/tessdata_fast |
|
||||
|
||||
---
|
||||
|
||||
## 方法三:自訂 Dockerfile(推薦生產環境)
|
||||
|
||||
### 步驟 1:建立 Dockerfile
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile
|
||||
FROM ghcr.io/cysk003/convertx-cn:latest
|
||||
|
||||
# 安裝額外 OCR 語言包
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr-spa \
|
||||
tesseract-ocr-ita \
|
||||
tesseract-ocr-por \
|
||||
tesseract-ocr-rus \
|
||||
tesseract-ocr-ara \
|
||||
tesseract-ocr-hin \
|
||||
tesseract-ocr-vie \
|
||||
tesseract-ocr-tha \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 可選:驗證安裝
|
||||
RUN tesseract --list-langs
|
||||
```
|
||||
|
||||
### 步驟 2:配置 compose.yaml
|
||||
|
||||
```yaml
|
||||
# compose.yaml
|
||||
services:
|
||||
convertx:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: convertx-cn
|
||||
restart: unless-stopped
|
||||
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
|
||||
environment:
|
||||
- TZ=Asia/Taipei
|
||||
- JWT_SECRET=請改成你自己的長隨機字串-至少32個字元
|
||||
```
|
||||
|
||||
### 步驟 3:建置並啟動
|
||||
|
||||
```bash
|
||||
# 建置自訂 image
|
||||
docker compose build
|
||||
|
||||
# 啟動
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 目錄結構
|
||||
|
||||
```
|
||||
your-project/
|
||||
├── compose.yaml
|
||||
├── Dockerfile
|
||||
└── data/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 可用語言包完整列表
|
||||
|
||||
### 常用語言
|
||||
|
||||
| Tesseract 包名 | 語言代碼 | 語言 | 檔案大小(約) |
|
||||
| ------------------- | -------- | -------- | -------------- |
|
||||
| `tesseract-ocr-spa` | es | 西班牙文 | 5 MB |
|
||||
| `tesseract-ocr-ita` | it | 義大利文 | 4 MB |
|
||||
| `tesseract-ocr-por` | pt | 葡萄牙文 | 4 MB |
|
||||
| `tesseract-ocr-rus` | ru | 俄文 | 6 MB |
|
||||
| `tesseract-ocr-ara` | ar | 阿拉伯文 | 3 MB |
|
||||
| `tesseract-ocr-hin` | hi | 印地文 | 7 MB |
|
||||
| `tesseract-ocr-vie` | vi | 越南文 | 2 MB |
|
||||
| `tesseract-ocr-tha` | th | 泰文 | 5 MB |
|
||||
|
||||
### 歐洲語言
|
||||
|
||||
| Tesseract 包名 | 語言代碼 | 語言 |
|
||||
| ------------------- | -------- | ------------ |
|
||||
| `tesseract-ocr-swe` | sv | 瑞典文 |
|
||||
| `tesseract-ocr-dan` | da | 丹麥文 |
|
||||
| `tesseract-ocr-nor` | no | 挪威文 |
|
||||
| `tesseract-ocr-fin` | fi | 芬蘭文 |
|
||||
| `tesseract-ocr-pol` | pl | 波蘭文 |
|
||||
| `tesseract-ocr-ces` | cs | 捷克文 |
|
||||
| `tesseract-ocr-hun` | hu | 匈牙利文 |
|
||||
| `tesseract-ocr-nld` | nl | 荷蘭文 |
|
||||
| `tesseract-ocr-ell` | el | 希臘文 |
|
||||
| `tesseract-ocr-ukr` | uk | 烏克蘭文 |
|
||||
| `tesseract-ocr-ron` | ro | 羅馬尼亞文 |
|
||||
| `tesseract-ocr-bul` | bg | 保加利亞文 |
|
||||
| `tesseract-ocr-hrv` | hr | 克羅地亞文 |
|
||||
| `tesseract-ocr-slk` | sk | 斯洛伐克文 |
|
||||
| `tesseract-ocr-slv` | sl | 斯洛維尼亞文 |
|
||||
|
||||
### 中東語言
|
||||
|
||||
| Tesseract 包名 | 語言代碼 | 語言 |
|
||||
| ------------------- | -------- | -------- |
|
||||
| `tesseract-ocr-heb` | he | 希伯來文 |
|
||||
| `tesseract-ocr-tur` | tr | 土耳其文 |
|
||||
| `tesseract-ocr-fas` | fa | 波斯文 |
|
||||
|
||||
### 亞洲語言
|
||||
|
||||
| Tesseract 包名 | 語言代碼 | 語言 |
|
||||
| ------------------- | -------- | ------------ |
|
||||
| `tesseract-ocr-ben` | bn | 孟加拉文 |
|
||||
| `tesseract-ocr-tam` | ta | 泰米爾文 |
|
||||
| `tesseract-ocr-tel` | te | 泰盧固文 |
|
||||
| `tesseract-ocr-kan` | kn | 卡納達文 |
|
||||
| `tesseract-ocr-mal` | ml | 馬拉雅拉姆文 |
|
||||
| `tesseract-ocr-mar` | mr | 馬拉地文 |
|
||||
| `tesseract-ocr-guj` | gu | 古吉拉特文 |
|
||||
| `tesseract-ocr-pan` | pa | 旁遮普文 |
|
||||
| `tesseract-ocr-mya` | my | 緬甸文 |
|
||||
| `tesseract-ocr-khm` | km | 高棉文 |
|
||||
| `tesseract-ocr-lao` | lo | 寮文 |
|
||||
| `tesseract-ocr-ind` | id | 印尼文 |
|
||||
| `tesseract-ocr-msa` | ms | 馬來文 |
|
||||
|
||||
> 💡 **查詢所有可用語言包**:在容器內執行 `apt-cache search tesseract-ocr-`
|
||||
|
||||
---
|
||||
|
||||
## 驗證語言包安裝
|
||||
|
||||
### 方法 1:在容器內檢查
|
||||
|
||||
```bash
|
||||
# 進入容器
|
||||
docker exec -it convertx-cn /bin/bash
|
||||
|
||||
# 列出已安裝的語言
|
||||
tesseract --list-langs
|
||||
```
|
||||
|
||||
### 方法 2:透過日誌確認
|
||||
|
||||
啟動容器後查看日誌:
|
||||
|
||||
```bash
|
||||
docker compose logs -f convertx
|
||||
```
|
||||
|
||||
如果使用方法一(compose.yaml 安裝),會看到類似以下輸出:
|
||||
|
||||
```
|
||||
📦 正在安裝額外 OCR 語言包...
|
||||
✅ 語言包安裝完成
|
||||
🚀 啟動 ConvertX...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常見問題
|
||||
|
||||
### Q: 為什麼 UI 上看不到新增的語言選項?
|
||||
|
||||
**A:** OCRmyPDF 的 UI 格式是在程式碼中固定的(8 種選項),新增語言包只會影響 `pdf-ocr` 自動模式的辨識能力。如果你使用 `pdf-ocr` 模式,系統會自動使用所有已安裝的語言包。
|
||||
|
||||
### Q: 自動模式會變慢嗎?
|
||||
|
||||
**A:** 安裝更多語言包後,`pdf-ocr` 自動模式可能會稍微變慢,因為 Tesseract 需要嘗試更多語言。如果你知道文件語言,選擇特定語言格式會更快。
|
||||
|
||||
### Q: 如何在 UI 上顯示新的語言選項?
|
||||
|
||||
**A:** 需要修改 `src/converters/ocrmypdf.ts` 中的 `SUPPORTED_LANGUAGES` 陣列,並重新建置應用。這超出了簡單配置的範圍。
|
||||
|
||||
### Q: 語言包太大,如何減少下載量?
|
||||
|
||||
**A:** 使用 `tessdata_fast` 版本而非 `tessdata_best`,或只安裝實際需要的語言。
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- [OCR 功能說明](../功能說明/OCR.md)
|
||||
- [Docker Compose 說明](說明文件.md)
|
||||
- [compose.ocr-languages.yml](compose.ocr-languages.yml)
|
||||
- [環境變數設定](../配置設定/環境變數.md)
|
||||
96
docs/Docker組合配置/compose.ocr-languages.yml
Normal file
96
docs/Docker組合配置/compose.ocr-languages.yml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# ==============================================================================
|
||||
# ConvertX-CN OCR 語言擴展配置
|
||||
#
|
||||
# 📚 此配置示範如何在容器啟動時安裝額外的 Tesseract OCR 語言包
|
||||
#
|
||||
# 🎯 適用情境:
|
||||
# - 需要 OCR 辨識西班牙文、義大利文、俄文等額外語言
|
||||
# - 翻譯引擎支援 15 種語言,但 OCR 預設只內建 8 種
|
||||
# - 需要處理更多語言的掃描版 PDF
|
||||
#
|
||||
# ⚠️ 注意事項:
|
||||
# - 每次容器啟動時都會安裝語言包,首次啟動較慢
|
||||
# - 語言包會存在容器內,重啟後需重新安裝
|
||||
# - 若需永久安裝,請使用自訂 Dockerfile 方式
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
services:
|
||||
convertx:
|
||||
image: convertx/convertx-cn:latest
|
||||
container_name: convertx-cn
|
||||
restart: unless-stopped
|
||||
|
||||
# =========================================================================
|
||||
# 使用自訂 entrypoint 安裝額外語言包
|
||||
# =========================================================================
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
echo "📦 正在安裝額外 OCR 語言包..."
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr-spa \
|
||||
tesseract-ocr-ita \
|
||||
tesseract-ocr-por \
|
||||
tesseract-ocr-rus \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
echo "✅ 語言包安裝完成"
|
||||
echo "🚀 啟動 ConvertX..."
|
||||
exec bun run start
|
||||
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
|
||||
environment:
|
||||
- TZ=Asia/Taipei
|
||||
- JWT_SECRET=請改成你自己的長隨機字串-至少32個字元
|
||||
- ACCOUNT_REGISTRATION=true
|
||||
- HTTP_ALLOWED=true
|
||||
- ALLOW_UNAUTHENTICATED=false
|
||||
- AUTO_DELETE_EVERY_N_HOURS=24
|
||||
|
||||
# ==============================================================================
|
||||
# 可用語言包對照表
|
||||
# ==============================================================================
|
||||
#
|
||||
# 💡 只需安裝你需要的語言,不必全部安裝
|
||||
#
|
||||
# 語言包名稱 | 語言代碼 | 語言
|
||||
# ----------------------|---------|----------------
|
||||
# tesseract-ocr-spa | es | 西班牙文
|
||||
# tesseract-ocr-ita | it | 義大利文
|
||||
# tesseract-ocr-por | pt | 葡萄牙文
|
||||
# tesseract-ocr-rus | ru | 俄文
|
||||
# tesseract-ocr-ara | ar | 阿拉伯文
|
||||
# tesseract-ocr-hin | hi | 印地文
|
||||
# tesseract-ocr-vie | vi | 越南文
|
||||
# tesseract-ocr-tha | th | 泰文
|
||||
# tesseract-ocr-swe | sv | 瑞典文
|
||||
# tesseract-ocr-dan | da | 丹麥文
|
||||
# tesseract-ocr-nor | no | 挪威文
|
||||
# tesseract-ocr-fin | fi | 芬蘭文
|
||||
# tesseract-ocr-pol | pl | 波蘭文
|
||||
# tesseract-ocr-ces | cs | 捷克文
|
||||
# tesseract-ocr-hun | hu | 匈牙利文
|
||||
# tesseract-ocr-tur | tr | 土耳其文
|
||||
# tesseract-ocr-heb | he | 希伯來文
|
||||
# tesseract-ocr-ben | bn | 孟加拉文
|
||||
# tesseract-ocr-tam | ta | 泰米爾文
|
||||
# tesseract-ocr-ind | id | 印尼文
|
||||
#
|
||||
# ==============================================================================
|
||||
# 內建語言(無需額外安裝)
|
||||
# ==============================================================================
|
||||
#
|
||||
# tesseract-ocr-eng | en | 英文
|
||||
# tesseract-ocr-chi-tra | zh-TW | 繁體中文
|
||||
# tesseract-ocr-chi-sim | zh | 簡體中文
|
||||
# tesseract-ocr-jpn | ja | 日文
|
||||
# tesseract-ocr-kor | ko | 韓文
|
||||
# tesseract-ocr-deu | de | 德文
|
||||
# tesseract-ocr-fra | fr | 法文
|
||||
#
|
||||
# ==============================================================================
|
||||
|
|
@ -4,20 +4,23 @@
|
|||
|
||||
## 範例檔案
|
||||
|
||||
| 檔案 | 適用情境 | 說明 |
|
||||
| ------------------------------------------------ | ----------- | --------------------- |
|
||||
| [compose.minimal.yml](compose.minimal.yml) | Docker 老手 | 最精簡的可用配置 |
|
||||
| [compose.production.yml](compose.production.yml) | 生產環境 | 含 Reverse Proxy 設定 |
|
||||
| [compose.reference.yml](compose.reference.yml) | 參考文件 | 所有設定的完整參考 |
|
||||
| 檔案 | 適用情境 | 說明 |
|
||||
| ------------------------------------------------------ | ----------- | --------------------- |
|
||||
| [compose.minimal.yml](compose.minimal.yml) | Docker 老手 | 最精簡的可用配置 |
|
||||
| [compose.production.yml](compose.production.yml) | 生產環境 | 含 Reverse Proxy 設定 |
|
||||
| [compose.reference.yml](compose.reference.yml) | 參考文件 | 所有設定的完整參考 |
|
||||
| [compose.ocr-languages.yml](compose.ocr-languages.yml) | OCR 擴展 | 安裝額外 OCR 語言包 |
|
||||
| [OCR語言擴展.md](OCR語言擴展.md) | 詳細指南 | OCR 語言擴展完整說明 |
|
||||
|
||||
## 快速選擇
|
||||
|
||||
| 你是... | 使用 |
|
||||
| ------------ | ----------------------------- |
|
||||
| 新手 | [README 主頁](../說明文件.md) |
|
||||
| Docker 熟手 | compose.minimal.yml |
|
||||
| 生產環境 | compose.production.yml |
|
||||
| 查詢所有選項 | compose.reference.yml |
|
||||
| 你是... | 使用 |
|
||||
| ----------------- | -------------------------------------------- |
|
||||
| 新手 | [README 主頁](../說明文件.md) |
|
||||
| Docker 熟手 | compose.minimal.yml |
|
||||
| 生產環境 | compose.production.yml |
|
||||
| 查詢所有選項 | compose.reference.yml |
|
||||
| 需要更多 OCR 語言 | [OCR語言擴展.md](OCR語言擴展.md)(詳細指南) |
|
||||
|
||||
## 如何使用
|
||||
|
||||
|
|
@ -55,3 +58,17 @@ docker compose up -d
|
|||
### 我想了解所有設定
|
||||
|
||||
參考 [compose.reference.yml](compose.reference.yml),包含所有環境變數的說明。
|
||||
|
||||
### 我需要更多 OCR 語言支援
|
||||
|
||||
參考 [OCR語言擴展.md](OCR語言擴展.md),這是完整的 OCR 語言擴展指南,包含:
|
||||
|
||||
- 三種擴展方法的詳細說明與比較
|
||||
- 完整的 compose.yaml 範例配置
|
||||
- 50+ 種可用語言包列表
|
||||
- 語言包下載與驗證方法
|
||||
- 常見問題解答
|
||||
|
||||
> 💡 內建 OCR 語言:英文、繁體中文、簡體中文、日文、韓文、德文、法文
|
||||
>
|
||||
> 翻譯引擎支援 15 種語言,但 OCR 預設只內建 8 種
|
||||
|
|
|
|||
|
|
@ -131,41 +131,47 @@ eng + chi_tra + chi_sim + jpn + kor + deu + fra
|
|||
|
||||
## 新增語言
|
||||
|
||||
### 方法一:自訂 Dockerfile
|
||||
ConvertX-CN 預設內建 7 種 OCR 語言,但你可以透過 Docker Compose 配置擴展支援更多語言。
|
||||
|
||||
> 💡 在 `Dockerfile.full` 中取消註解以下內容
|
||||
### 擴展方法
|
||||
|
||||
```dockerfile
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr-spa \
|
||||
tesseract-ocr-ita \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
```
|
||||
| 方法 | 說明 | 適用場景 |
|
||||
| ----------------- | -------------------------- | -------------- |
|
||||
| compose.yaml 安裝 | 容器啟動時自動安裝語言包 | 測試、臨時使用 |
|
||||
| 掛載語言包 | 下載 .traineddata 檔案掛載 | 離線環境 |
|
||||
| 自訂 Dockerfile | 建置包含語言包的自訂映像 | 生產環境 |
|
||||
|
||||
- `tesseract-ocr-spa` — 西班牙文
|
||||
- `tesseract-ocr-ita` — 義大利文
|
||||
### 常用可選語言
|
||||
|
||||
### 方法二:掛載語言包
|
||||
| Tesseract 包名 | 語言 |
|
||||
| ------------------- | -------- |
|
||||
| `tesseract-ocr-spa` | 西班牙文 |
|
||||
| `tesseract-ocr-ita` | 義大利文 |
|
||||
| `tesseract-ocr-por` | 葡萄牙文 |
|
||||
| `tesseract-ocr-rus` | 俄文 |
|
||||
| `tesseract-ocr-ara` | 阿拉伯文 |
|
||||
| `tesseract-ocr-vie` | 越南文 |
|
||||
| `tesseract-ocr-tha` | 泰文 |
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ./tessdata:/usr/share/tesseract-ocr/5/tessdata
|
||||
```
|
||||
|
||||
下載語言包:https://github.com/tesseract-ocr/tessdata_best
|
||||
> 📖 **詳細配置指南**:[OCR 語言擴展指南](../Docker組合配置/OCR語言擴展.md)
|
||||
>
|
||||
> 包含完整的 compose.yaml 範例、語言包下載方法、以及 50+ 種可用語言列表。
|
||||
|
||||
---
|
||||
|
||||
## 可選語言包
|
||||
## OCRmyPDF vs 翻譯引擎語言支援
|
||||
|
||||
| 區域 | 語言 |
|
||||
| ------ | ------------------------------ |
|
||||
| 西歐 | 西班牙文、義大利文、葡萄牙文 |
|
||||
| 北歐 | 瑞典文、丹麥文、挪威文、芬蘭文 |
|
||||
| 東歐 | 俄文、波蘭文、捷克文、匈牙利文 |
|
||||
| 中東 | 阿拉伯文、希伯來文、土耳其文 |
|
||||
| 南亞 | 印地文、孟加拉文、泰米爾文 |
|
||||
| 東南亞 | 泰文、越南文、印尼文 |
|
||||
| 功能 | OCRmyPDF | PDFMathTranslate / BabelDOC |
|
||||
| -------- | --------------------------- | --------------------------- |
|
||||
| 內建語言 | 8 種 | 15 種 |
|
||||
| 可擴展 | ✅ 可透過 compose.yaml 添加 | ❌ 固定 |
|
||||
| 語言用途 | OCR 文字辨識 | 翻譯目標語言 |
|
||||
|
||||
**OCRmyPDF 內建語言**:英文、繁體中文、簡體中文、日文、韓文、德文、法文 + 自動多語言模式
|
||||
|
||||
**翻譯引擎內建語言**:英文、簡體中文、繁體中文、日文、韓文、德文、法文、西班牙文、義大利文、葡萄牙文、俄文、阿拉伯文、印地文、越南文、泰文
|
||||
|
||||
> 💡 如果需要 OCR 更多語言,請參考 [OCR 語言擴展指南](../Docker組合配置/OCR語言擴展.md)。
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -173,4 +179,5 @@ volumes:
|
|||
|
||||
- [支援的轉換器](轉換器.md)
|
||||
- [翻譯功能](翻譯功能.md)
|
||||
- [OCR 語言擴展指南](../Docker組合配置/OCR語言擴展.md)
|
||||
- [Docker 部署](../部署指南/Docker部署.md)
|
||||
|
|
|
|||
|
|
@ -75,6 +75,17 @@ ConvertX-CN 內建兩個 PDF 翻譯引擎:
|
|||
|
||||
> 💡 BabelDOC 額外支援 `md-<lang>` 和 `html-<lang>` 格式
|
||||
|
||||
### 與 OCRmyPDF 語言差異
|
||||
|
||||
| 功能 | 翻譯引擎 | OCRmyPDF |
|
||||
| -------- | ------------ | -------------- |
|
||||
| 支援語言 | 15 種 | 8 種(可擴展) |
|
||||
| 用途 | 翻譯目標語言 | OCR 文字辨識 |
|
||||
|
||||
翻譯引擎支援 15 種目標語言,而 OCRmyPDF 預設只內建 8 種 OCR 語言。
|
||||
|
||||
如需擴展 OCRmyPDF 語言支援,請參考 [OCR 功能 - 新增語言](OCR.md#新增語言)。
|
||||
|
||||
---
|
||||
|
||||
## 輸出格式
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ ConvertX-CN 是 fork 自 [C4illin/ConvertX](https://github.com/C4illin/ConvertX)
|
|||
| CJK 字型 | ❌ | ✅ Noto CJK + 標楷體 |
|
||||
| TexLive | 基本 | 完整 |
|
||||
| 繁中介面 | ❌ | ✅ 預設 |
|
||||
| MinerU | ❌ | ✅ 包含 |
|
||||
| MinerU | ❌ | ✅ 包含 |
|
||||
| PDF 翻譯 | ❌ | ✅ PDFMathTranslate |
|
||||
|
||||
---
|
||||
|
|
|
|||
96
docs/範例配置/compose.ocr-languages.yml
Normal file
96
docs/範例配置/compose.ocr-languages.yml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# ==============================================================================
|
||||
# ConvertX-CN OCR 語言擴展配置
|
||||
#
|
||||
# 📚 此配置示範如何在容器啟動時安裝額外的 Tesseract OCR 語言包
|
||||
#
|
||||
# 🎯 適用情境:
|
||||
# - 需要 OCR 辨識西班牙文、義大利文、俄文等額外語言
|
||||
# - 翻譯引擎支援 15 種語言,但 OCR 預設只內建 8 種
|
||||
# - 需要處理更多語言的掃描版 PDF
|
||||
#
|
||||
# ⚠️ 注意事項:
|
||||
# - 每次容器啟動時都會安裝語言包,首次啟動較慢
|
||||
# - 語言包會存在容器內,重啟後需重新安裝
|
||||
# - 若需永久安裝,請使用自訂 Dockerfile 方式
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
services:
|
||||
convertx:
|
||||
image: convertx/convertx-cn:latest
|
||||
container_name: convertx-cn
|
||||
restart: unless-stopped
|
||||
|
||||
# =========================================================================
|
||||
# 使用自訂 entrypoint 安裝額外語言包
|
||||
# =========================================================================
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
echo "📦 正在安裝額外 OCR 語言包..."
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr-spa \
|
||||
tesseract-ocr-ita \
|
||||
tesseract-ocr-por \
|
||||
tesseract-ocr-rus \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
echo "✅ 語言包安裝完成"
|
||||
echo "🚀 啟動 ConvertX..."
|
||||
exec bun run start
|
||||
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
|
||||
environment:
|
||||
- TZ=Asia/Taipei
|
||||
- JWT_SECRET=請改成你自己的長隨機字串-至少32個字元
|
||||
- ACCOUNT_REGISTRATION=true
|
||||
- HTTP_ALLOWED=true
|
||||
- ALLOW_UNAUTHENTICATED=false
|
||||
- AUTO_DELETE_EVERY_N_HOURS=24
|
||||
|
||||
# ==============================================================================
|
||||
# 可用語言包對照表
|
||||
# ==============================================================================
|
||||
#
|
||||
# 💡 只需安裝你需要的語言,不必全部安裝
|
||||
#
|
||||
# 語言包名稱 | 語言代碼 | 語言
|
||||
# ----------------------|---------|----------------
|
||||
# tesseract-ocr-spa | es | 西班牙文
|
||||
# tesseract-ocr-ita | it | 義大利文
|
||||
# tesseract-ocr-por | pt | 葡萄牙文
|
||||
# tesseract-ocr-rus | ru | 俄文
|
||||
# tesseract-ocr-ara | ar | 阿拉伯文
|
||||
# tesseract-ocr-hin | hi | 印地文
|
||||
# tesseract-ocr-vie | vi | 越南文
|
||||
# tesseract-ocr-tha | th | 泰文
|
||||
# tesseract-ocr-swe | sv | 瑞典文
|
||||
# tesseract-ocr-dan | da | 丹麥文
|
||||
# tesseract-ocr-nor | no | 挪威文
|
||||
# tesseract-ocr-fin | fi | 芬蘭文
|
||||
# tesseract-ocr-pol | pl | 波蘭文
|
||||
# tesseract-ocr-ces | cs | 捷克文
|
||||
# tesseract-ocr-hun | hu | 匈牙利文
|
||||
# tesseract-ocr-tur | tr | 土耳其文
|
||||
# tesseract-ocr-heb | he | 希伯來文
|
||||
# tesseract-ocr-ben | bn | 孟加拉文
|
||||
# tesseract-ocr-tam | ta | 泰米爾文
|
||||
# tesseract-ocr-ind | id | 印尼文
|
||||
#
|
||||
# ==============================================================================
|
||||
# 內建語言(無需額外安裝)
|
||||
# ==============================================================================
|
||||
#
|
||||
# tesseract-ocr-eng | en | 英文
|
||||
# tesseract-ocr-chi-tra | zh-TW | 繁體中文
|
||||
# tesseract-ocr-chi-sim | zh | 簡體中文
|
||||
# tesseract-ocr-jpn | ja | 日文
|
||||
# tesseract-ocr-kor | ko | 韓文
|
||||
# tesseract-ocr-deu | de | 德文
|
||||
# tesseract-ocr-fra | fr | 法文
|
||||
#
|
||||
# ==============================================================================
|
||||
|
|
@ -6,12 +6,13 @@
|
|||
|
||||
## 範例檔案
|
||||
|
||||
| 檔案 | 用途 | 說明 |
|
||||
| -------------------------- | ---------- | ---------------- |
|
||||
| `compose.minimal.yml` | 快速啟動 | 最精簡配置 |
|
||||
| `compose.production.yml` | 生產環境 | 包含安全設定 |
|
||||
| `compose.with-traefik.yml` | 反向代理 | Traefik 整合 |
|
||||
| `nginx.example.conf` | Nginx 設定 | 反向代理設定範例 |
|
||||
| 檔案 | 用途 | 說明 |
|
||||
| --------------------------- | ------------ | ----------------- |
|
||||
| `最小配置.yml` | 快速啟動 | 最精簡配置 |
|
||||
| `生產環境配置.yml` | 生產環境 | 包含安全設定 |
|
||||
| `compose.ocr-languages.yml` | OCR 語言擴展 | 安裝額外 OCR 語言 |
|
||||
| `Traefik配置.yml` | 反向代理 | Traefik 整合 |
|
||||
| `Nginx範例配置.conf` | Nginx 設定 | 反向代理設定範例 |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { execFile as execFileOriginal } from "node:child_process";
|
||||
import { mkdirSync, existsSync, readdirSync, unlinkSync, rmdirSync, statSync } from "node:fs";
|
||||
import { mkdirSync, existsSync, readdirSync, unlinkSync, rmdirSync } from "node:fs";
|
||||
import { join, basename, dirname } from "node:path";
|
||||
import { ExecFileFn } from "./types";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { test, expect, describe, mock } from "bun:test";
|
||||
import { convert, properties } from "../../src/converters/deark";
|
||||
import type { ExecFileFn } from "../../src/converters/types";
|
||||
|
||||
describe("deark converter", () => {
|
||||
test("properties should have correct structure", () => {
|
||||
|
|
@ -9,32 +10,34 @@ describe("deark converter", () => {
|
|||
expect(properties.outputMode).toBe("archive");
|
||||
});
|
||||
|
||||
test("properties.from should contain archive formats", () => {
|
||||
expect(properties.from.archive).toBeDefined();
|
||||
expect(properties.from.archive).toContain("zip");
|
||||
expect(properties.from.archive).toContain("lha");
|
||||
expect(properties.from.archive).toContain("arc");
|
||||
test("properties.from should contain supported formats", () => {
|
||||
expect(properties.from.files).toBeDefined();
|
||||
// Archive formats
|
||||
expect(properties.from.files).toContain("zip");
|
||||
expect(properties.from.files).toContain("lha");
|
||||
expect(properties.from.files).toContain("arc");
|
||||
// Image formats
|
||||
expect(properties.from.files).toContain("ico");
|
||||
expect(properties.from.files).toContain("bmp");
|
||||
expect(properties.from.files).toContain("pcx");
|
||||
});
|
||||
|
||||
test("properties.from should contain image formats", () => {
|
||||
expect(properties.from.images).toBeDefined();
|
||||
expect(properties.from.images).toContain("ico");
|
||||
expect(properties.from.images).toContain("bmp");
|
||||
expect(properties.from.images).toContain("pcx");
|
||||
});
|
||||
|
||||
test("properties.to should have extract option for all categories", () => {
|
||||
for (const category of Object.keys(properties.from)) {
|
||||
expect(properties.to[category]).toBeDefined();
|
||||
expect(properties.to[category]).toContain("extract");
|
||||
}
|
||||
test("properties.to should have extract option", () => {
|
||||
expect(properties.to.files).toBeDefined();
|
||||
expect(properties.to.files).toContain("extract");
|
||||
});
|
||||
|
||||
test("convert resolves when execFile succeeds", async () => {
|
||||
const mockExecFile = mock((cmd: string, args: string[], callback: Function) => {
|
||||
// First call is deark, second call is tar
|
||||
callback(null, "Success", "");
|
||||
});
|
||||
const mockExecFile = mock(
|
||||
(
|
||||
cmd: string,
|
||||
args: string[],
|
||||
callback: (error: Error | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
// First call is deark, second call is tar
|
||||
callback(null, "Success", "");
|
||||
},
|
||||
);
|
||||
|
||||
// Mock fs functions would be needed for full test
|
||||
// This is a simplified test
|
||||
|
|
@ -45,7 +48,7 @@ describe("deark converter", () => {
|
|||
"extract",
|
||||
"/tmp/output/test",
|
||||
{},
|
||||
mockExecFile as any,
|
||||
mockExecFile as ExecFileFn,
|
||||
);
|
||||
} catch (error) {
|
||||
// Expected to fail due to fs operations not being mocked
|
||||
|
|
@ -54,9 +57,15 @@ describe("deark converter", () => {
|
|||
});
|
||||
|
||||
test("convert rejects when deark fails", async () => {
|
||||
const mockExecFile = mock((cmd: string, args: string[], callback: Function) => {
|
||||
callback(new Error("deark failed"), "", "Unknown or unsupported format");
|
||||
});
|
||||
const mockExecFile = mock(
|
||||
(
|
||||
cmd: string,
|
||||
args: string[],
|
||||
callback: (error: Error | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
callback(new Error("deark failed"), "", "Unknown or unsupported format");
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
await convert(
|
||||
|
|
@ -65,7 +74,7 @@ describe("deark converter", () => {
|
|||
"extract",
|
||||
"/tmp/output/test",
|
||||
{},
|
||||
mockExecFile as any,
|
||||
mockExecFile as ExecFileFn,
|
||||
);
|
||||
expect(true).toBe(false); // Should not reach here
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,25 @@ describe("FFmpeg 格式", () => {
|
|||
const toFormats = ffmpegProps.to.muxer;
|
||||
|
||||
// 關鍵影片格式(wmv 由 asf 處理)
|
||||
const keyVideoFormats = ["264", "265", "3g2", "3gp", "asf", "av1", "avi", "flv", "h264", "h265", "hevc", "mkv", "mov", "mp4", "mpeg", "mpg", "webm"];
|
||||
const keyVideoFormats = [
|
||||
"264",
|
||||
"265",
|
||||
"3g2",
|
||||
"3gp",
|
||||
"asf",
|
||||
"av1",
|
||||
"avi",
|
||||
"flv",
|
||||
"h264",
|
||||
"h265",
|
||||
"hevc",
|
||||
"mkv",
|
||||
"mov",
|
||||
"mp4",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"webm",
|
||||
];
|
||||
// 關鍵音訊格式
|
||||
const keyAudioFormats = ["aac", "ac3", "aiff", "flac", "m4a", "mp3", "ogg", "opus", "wav", "wma"];
|
||||
// 關鍵字幕格式
|
||||
|
|
@ -110,7 +128,21 @@ describe("ImageMagick 格式", () => {
|
|||
// 關鍵 RAW 相機格式
|
||||
const keyRawFormats = ["arw", "cr2", "cr3", "dng", "nef", "orf", "raf"];
|
||||
// 關鍵常見圖片格式
|
||||
const keyImageFormats = ["apng", "avif", "bmp", "gif", "heic", "heif", "ico", "jpeg", "jpg", "jxl", "png", "tiff", "webp"];
|
||||
const keyImageFormats = [
|
||||
"apng",
|
||||
"avif",
|
||||
"bmp",
|
||||
"gif",
|
||||
"heic",
|
||||
"heif",
|
||||
"ico",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"jxl",
|
||||
"png",
|
||||
"tiff",
|
||||
"webp",
|
||||
];
|
||||
// 關鍵向量格式
|
||||
const keyVectorFormats = ["eps", "pdf", "ps", "psd", "svg"];
|
||||
|
||||
|
|
@ -913,8 +945,16 @@ describe("PDFMathTranslate 格式", () => {
|
|||
const toFormats = pdfmathtranslateProps.to.document;
|
||||
|
||||
const keyOutputFormats = [
|
||||
"pdf-en", "pdf-zh", "pdf-zh-TW", "pdf-ja", "pdf-ko",
|
||||
"pdf-de", "pdf-fr", "pdf-es", "pdf-it", "pdf-ru"
|
||||
"pdf-en",
|
||||
"pdf-zh",
|
||||
"pdf-zh-TW",
|
||||
"pdf-ja",
|
||||
"pdf-ko",
|
||||
"pdf-de",
|
||||
"pdf-fr",
|
||||
"pdf-es",
|
||||
"pdf-it",
|
||||
"pdf-ru",
|
||||
];
|
||||
|
||||
test("輸入格式應為 pdf", () => {
|
||||
|
|
@ -1011,7 +1051,13 @@ describe("OCRmyPDF 格式", () => {
|
|||
const toFormats = ocrmypdfProps.to.document;
|
||||
|
||||
const keyOutputFormats = [
|
||||
"pdf-en", "pdf-zh-TW", "pdf-zh", "pdf-ja", "pdf-ko", "pdf-de", "pdf-fr"
|
||||
"pdf-en",
|
||||
"pdf-zh-TW",
|
||||
"pdf-zh",
|
||||
"pdf-ja",
|
||||
"pdf-ko",
|
||||
"pdf-de",
|
||||
"pdf-fr",
|
||||
];
|
||||
|
||||
test("輸入格式應為 pdf", () => {
|
||||
|
|
@ -1029,8 +1075,8 @@ describe("OCRmyPDF 格式", () => {
|
|||
console.log(`OCRmyPDF 輸入格式:${fromFormats.length} 種`);
|
||||
});
|
||||
|
||||
test("輸出格式數量應等於 7 種", () => {
|
||||
expect(toFormats.length).toBe(7);
|
||||
test("輸出格式數量應等於 8 種", () => {
|
||||
expect(toFormats.length).toBe(8);
|
||||
console.log(`OCRmyPDF 輸出格式:${toFormats.length} 種`);
|
||||
});
|
||||
|
||||
|
|
@ -1081,14 +1127,38 @@ describe("格式總覽", () => {
|
|||
|
||||
const summary = [
|
||||
{ name: "FFmpeg", from: ffmpegProps.from.muxer.length, to: ffmpegProps.to.muxer.length },
|
||||
{ name: "ImageMagick", from: imagemagickProps.from.images.length, to: imagemagickProps.to.images.length },
|
||||
{ name: "GraphicsMagick", from: graphicsmagickProps.from.image.length, to: graphicsmagickProps.to.image.length },
|
||||
{
|
||||
name: "ImageMagick",
|
||||
from: imagemagickProps.from.images.length,
|
||||
to: imagemagickProps.to.images.length,
|
||||
},
|
||||
{
|
||||
name: "GraphicsMagick",
|
||||
from: graphicsmagickProps.from.image.length,
|
||||
to: graphicsmagickProps.to.image.length,
|
||||
},
|
||||
{ name: "Vips", from: vipsProps.from.images.length, to: vipsProps.to.images.length },
|
||||
{ name: "LibreOffice", from: libreofficeProps.from.text.length, to: libreofficeProps.to.text.length },
|
||||
{
|
||||
name: "LibreOffice",
|
||||
from: libreofficeProps.from.text.length,
|
||||
to: libreofficeProps.to.text.length,
|
||||
},
|
||||
{ name: "Pandoc", from: pandocProps.from.text.length, to: pandocProps.to.text.length },
|
||||
{ name: "Calibre", from: calibreProps.from.document.length, to: calibreProps.to.document.length },
|
||||
{ name: "Inkscape", from: inkscapeProps.from.images.length, to: inkscapeProps.to.images.length },
|
||||
{ name: "libjxl", from: libjxlProps.from.jxl.length + libjxlProps.from.images.length, to: libjxlProps.to.jxl.length + libjxlProps.to.images.length },
|
||||
{
|
||||
name: "Calibre",
|
||||
from: calibreProps.from.document.length,
|
||||
to: calibreProps.to.document.length,
|
||||
},
|
||||
{
|
||||
name: "Inkscape",
|
||||
from: inkscapeProps.from.images.length,
|
||||
to: inkscapeProps.to.images.length,
|
||||
},
|
||||
{
|
||||
name: "libjxl",
|
||||
from: libjxlProps.from.jxl.length + libjxlProps.from.images.length,
|
||||
to: libjxlProps.to.jxl.length + libjxlProps.to.images.length,
|
||||
},
|
||||
{ name: "libheif", from: libheifProps.from.images.length, to: libheifProps.to.images.length },
|
||||
{ name: "Assimp", from: assimpProps.from.object.length, to: assimpProps.to.object.length },
|
||||
{ name: "Potrace", from: potraceProps.from.images.length, to: potraceProps.to.images.length },
|
||||
|
|
@ -1097,13 +1167,37 @@ describe("格式總覽", () => {
|
|||
{ name: "XeLaTeX", from: xelatexProps.from.text.length, to: xelatexProps.to.text.length },
|
||||
{ name: "dvisvgm", from: dvisvgmProps.from.images.length, to: dvisvgmProps.to.images.length },
|
||||
{ name: "Dasel", from: daselProps.from.document.length, to: daselProps.to.document.length },
|
||||
{ name: "msgconvert", from: msgconvertProps.from.email.length, to: msgconvertProps.to.email.length },
|
||||
{
|
||||
name: "msgconvert",
|
||||
from: msgconvertProps.from.email.length,
|
||||
to: msgconvertProps.to.email.length,
|
||||
},
|
||||
{ name: "VCF", from: vcfProps.from.contacts.length, to: vcfProps.to.contacts.length },
|
||||
{ name: "Markitdown", from: markitdownProps.from.document.length, to: markitdownProps.to.document.length },
|
||||
{ name: "MinerU", from: mineruProps.from.document.length, to: mineruProps.to.document.length },
|
||||
{ name: "PDFMathTranslate", from: pdfmathtranslateProps.from.document.length, to: pdfmathtranslateProps.to.document.length },
|
||||
{ name: "BabelDOC", from: babeldocProps.from.document.length, to: babeldocProps.to.document.length },
|
||||
{ name: "OCRmyPDF", from: ocrmypdfProps.from.document.length, to: ocrmypdfProps.to.document.length },
|
||||
{
|
||||
name: "Markitdown",
|
||||
from: markitdownProps.from.document.length,
|
||||
to: markitdownProps.to.document.length,
|
||||
},
|
||||
{
|
||||
name: "MinerU",
|
||||
from: mineruProps.from.document.length,
|
||||
to: mineruProps.to.document.length,
|
||||
},
|
||||
{
|
||||
name: "PDFMathTranslate",
|
||||
from: pdfmathtranslateProps.from.document.length,
|
||||
to: pdfmathtranslateProps.to.document.length,
|
||||
},
|
||||
{
|
||||
name: "BabelDOC",
|
||||
from: babeldocProps.from.document.length,
|
||||
to: babeldocProps.to.document.length,
|
||||
},
|
||||
{
|
||||
name: "OCRmyPDF",
|
||||
from: ocrmypdfProps.from.document.length,
|
||||
to: ocrmypdfProps.to.document.length,
|
||||
},
|
||||
];
|
||||
|
||||
let totalFrom = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue