🏛️ Janus:Claude的本地文档功能
即时TIFF的零拷贝网关↔ PDF转换 \ “不要只是转换文件。让你的人工智能读取历史记录。”
“JPEG2000编码的TIFF不能用标准图像查看器打开——它们需要专有的供应商特定软件。这个项目始于一个简单的想法:如果我们可以将它们转换为PDF并在任何标准网络浏览器中查看呢?”
 ](https://nodejs.org/)
概述
专为处理数百万扫描文档的AI/ML管道而设计。
@janus-mcp/converter 将高速扫描仪多页TIFF转换为针对AI训练和推理进行优化的归一化图像PDF。建于 零拷贝架构 实现企业级文档处理的最大吞吐量。
“投入就是创新,产出就是授权。” 我们处理传统格式的复杂性,因此您可以简单地将任务委托给AI。
设计目标
| 目标 | 解决方案 |
|---|---|
| 高性能 | 零拷贝架构-无解码/重新编码开销 |
| 高量 | 1900+页/秒吞吐量,异步非阻塞I/O |
| 格式规范化 | 专有标签(33004、34713)→标准34712 |
| 概念转换 | TIFF→PDF→TIFF→PDF生成相同的输出 |
| AI就绪输出 | 可在Chrome/Edge中查看OCR的标准化PDF |
主要特点
- ✅ 零拷贝架构:直接流提取,无需解码/重新编码
- ✅ 超高速性能:9页文档约4ms(1.9MB)
- ✅ 非阻塞异步:使用libuv线程池进行异步转换
- ✅ JPEG2000标准化:自动转换33004/34713→ 34712 (可选)
- ✅ 临时往返:TIFF↔PDF转换是完全可逆的
- ✅ 多页支持:将多页TIFF转换为多页PDF
- ✅ MPL 2.0许可证:具有copyleft保护的开源
为什么是@janus mcp/converter?
🔓 用例:专有TIFF的“通用查看器”
您是否正在努力处理无法在标准图像查看器中打开的专有TIFF文件(标签34712、34713)?
在金融和政府等领域(尤其是在韩国),TIFF经常使用特定于供应商的标签来包装标准JPEG2000流。这些需要昂贵的、依赖于操作系统的专有查看器。
Janus立即解决了这个问题:
- 提取物 来自专有TIFF容器的标准JPEG2000流。
- 派遣 使用Zero Copy将其复制到标准PDF容器中。
- 结果: 现在,您可以在中查看这些文件 任何标准PDF查看器 (Chrome、Edge、Acrobat、预览版)。
效果: Janus是一个高性能的开源转换器,可以将任何PDF阅读器变成传统专有文档的免费查看器。
Q: 我无法打开TIFF文件。它显示黑屏或错误。
A: 如果您的TIFF使用34712或34713等专有标签,标准查看器将无法打开它。Janus将这些标签转换为标准PDF,允许您在Chrome、Edge或Acrobat中免费查看。
安装
先决条件
Node.js
- Node.js:≥18.17.0、≥20.3.0或≥21.0.0
平台特定依赖关系
Linux(Ubuntu/Debian/Mint)
该软件包包括Linux x64(glibc≥2.31)的预构建二进制文件,但需要系统库:
检查是否安装了库:
# Check all required libraries at once
pkg-config --modversion libtiff-4 libopenjp2 libjpeg libturbojpeg zlib
# Expected output (each on separate line):
# 4.1.0 (libtiff-4)
# 2.3.1 (libopenjp2)
# 9.4.0 (libjpeg - provided by libjpeg-turbo)
# 3.0.0 (libturbojpeg - SIMD-accelerated API ⚡)
# 1.2.11 (zlib)如果缺少任何库,请安装开发包:
sudo apt-get update
sudo apt-get install -y \
libtiff-dev \
libopenjp2-7-dev \
libjpeg-turbo8-dev \
zlib1g-dev
# ⚡ libjpeg-turbo provides SIMD-accelerated JPEG processing
# AVX2/SSE2 support is automatically enabled on compatible CPUs验证安装和SIMD支持:
# Check library versions
pkg-config --modversion libtiff-4 libopenjp2 libjpeg libturbojpeg zlib
# Verify libjpeg-turbo is installed (not legacy libjpeg)
dpkg -l | grep libjpeg-turbo
# Should show: libjpeg-turbo8-dev (SIMD-enabled version)
# Check CPU SIMD capabilities
cat /proc/cpuinfo | grep -E "sse2|avx|avx2|avx512"
# Look for: avx2 (best), avx512f (server CPUs), or sse2 (minimum)
# Expected output (versions may vary):
# libtiff-4: 4.1.0+
# libopenjp2: 2.3.1+
# libjpeg: 9.4.0+ (legacy API, provided by libjpeg-turbo8-dev)
# libturbojpeg: 3.0.0+ (TurboJPEG API with SIMD ⚡)
# zlib: 1.2.11+分发兼容性:
- ✅ Ubuntu 20.04 LTS或更高版本(建议使用AVX2)
- ✅ Ubuntu 22.04 LTS,24.04 LTS
- ✅ Linux Mint 20或更高版本
- ✅ 爸!\_操作系统20.04或更高版本
- ✅ Debian 11(牛眼)或更高版本
- ✅ Fedora 35或更高版本
- ✅ RHEL 9或更高版本
macOS
# Install dependencies via Homebrew
brew install libtiff openjpeg jpeg-turbo
# ⚡ jpeg-turbo includes NEON SIMD support for Apple Silicon
# Automatically optimized for M1/M2/M3 processors验证NEON支持(苹果硅):
sysctl hw.optional.neon
# Output: hw.optional.neon: 1 (✅ SIMD enabled)视窗
包括预构建的二进制文件 -Windows x64不需要其他依赖项。
该包包括静态链接的二进制文件,其中嵌入了所有依赖项,包括 libjpeg-turbo支持AVX2/SSE2.
SIMD支持:
- ✅ 自动检测AVX2(2013年以后的Intel/AMD CPU)
- ✅ 在较旧的CPU上回退到SSE2
- ✅ 无需配置
NPM安装
npm install @janus-mcp/converter从源代码构建
git clone https://github.com/edwardkim/janus-mcp.git
cd mcp-janus-converter
npm install
npm run build用法
Claude桌面配置
添加到您的 claude_desktop_config.json:
{
"mcpServers": {
"janus-converter": {
"command": "npx",
"args": ["-y", "@janus-mcp/converter"]
}
}
}可用工具
1. convert_pdf_to_tiff
将PDF转换为多页TIFF。
输入架构:
{
"pdf_path": "/path/to/input.pdf",
"tiff_path": "/path/to/output.tif",
"verbose": false
}输出:
{
"success": true,
"message": "Conversion successful",
"input": {
"path": "/path/to/input.pdf",
"size": 1048576,
"sizeFormatted": "1.00 MB"
},
"output": {
"path": "/path/to/output.tif",
"size": 2097152,
"sizeFormatted": "2.00 MB",
"exists": true
},
"conversion": {
"pageCount": 9,
"elapsedMs": 4,
"avgMsPerPage": "0.44"
}
}2. convert_tiff_to_pdf
将TIFF转换为多页PDF。
输入架构:
{
"tiff_path": "/path/to/input.tif",
"pdf_path": "/path/to/output.pdf",
"verbose": false
}输出:结构与 convert_pdf_to_tiff
3. get_pdf_info
无需转换即可获取PDF文件信息。
输入架构:
{
"pdf_path": "/path/to/file.pdf"
}输出:
{
"success": true,
"path": "/path/to/file.pdf",
"exists": true,
"size": 1048576,
"sizeFormatted": "1.00 MB",
"isFile": true,
"isDirectory": false,
"error": null
}4. get_tiff_info
无需转换即可获取TIFF文件信息。
输入架构:与 get_pdf_info 但随着 tiff_path
API 参考
本机插件(pdf2tif.node)
ConvertSync(pdfPath, tiffPath, verbose)
同步转换(阻止事件循环)。
参数:
pdfPath(string):输入PDF文件路径tiffPath(字符串):输出TIFF文件路径verbose(boolean,可选):启用详细输出
退货:
{
success: boolean,
pageCount: number,
message: string
}ConvertAsync(pdfPath, tiffPath, verbose)
异步转换(非阻塞,返回Promise)。
参数:与 ConvertSync
退货: Promise
本地插件(tiff2pdf.node)
ConvertSync(tiffPath, pdfPath, verboseInt)
同步转换(阻止事件循环)。
参数:
tiffPath(string):输入TIFF文件路径pdfPath(string):输出PDF文件路径verboseInt(数字):详细标志(0或1)
退货:
{
success: boolean,
pageCount: number,
message: string
}ConvertAsync(tiffPath, pdfPath, verboseInt)
异步转换(非阻塞,返回Promise)。
参数:与 ConvertSync
退货: Promise
性能特征
🚀 零拷贝JPEG优化(新增!)
JPEG压缩TIFF的革命性性能改进:
| TIFF类型 | 条带/页 | 处理路径 | 时间/页 | 改进 |
|---|---|---|---|---|
| 单条JPEG | 1 | 零拷贝重建 | 0.8毫秒 | 493倍更快 |
| 多条JPEG | 293 | 解码→化解后撤 | 91.2毫秒 | 4.3倍更快 |
现实世界影响(1000万页):
- 之前:45.7天
- 之后:9.5天(混合场景:90%多条,10%单条)
- 储蓄:36.2天⚡
关键创新:
- ✅ 缩写与标准JPEGTABLES的自动检测
- ✅ 单条TIFF的零拷贝重建(0.8ms/页)
- ✅ 智能回退解码→多条带放气(91.2ms/页)
- ✅ Adobe Reader与ColorTransform检测的兼容性
- ✅ 高效的Deflate压缩(原始大小的10-16%)
技术细节:
- 支持标准的JPEGTABLES(SOS标记)和缩写的JPEGTABLE(现代标准)
- 处理具有独立标头的复杂多条JPEG结构
- 针对AI预处理工作流程和大容量文档处理进行了优化
🔬 扫描仪JPEG存储:第一页与后续页
经常被忽视的实施细节:高速文档扫描仪对第一页和后续页面的JPEG数据存储方式不同。虽然这在 TIFF技术说明#2,许多转换工具无法正确处理它,导致多页文档的输出损坏。
问题:
高速扫描仪通过重用JPEG量化和霍夫曼表来优化内存:
| 页面 | 存储方法 | JPEGTABLES标签 | 条带数据 |
|---|---|---|---|
| 首页 | 完整JPEG | ❌ 未使用 | 完整JPEG(SOI→ EOI) |
| 后续页面 | 缩写JPEG | ✅ 共享表 | 仅扫描数据(SOS→ EOI) |
First Page: [SOI][DQT][DHT][SOF][SOS]...image data...[EOI] ← Complete JPEG
└─────────────────────────────────────────┘
Stored in Strip
Subsequent Pages: [SOI][DQT][DHT] + [SOS]...image data...[EOI] ← Split storage
└──────────────┘ └─────────────────────┘
JPEGTABLES tag Strip data only现有工具失败的原因:
- 大多数库都假设所有页面具有相同的结构
- 它们要么错过了JPEGTABLES标签,要么无法重建完整的JPEG
- 结果:第一页转换正确,后续页面损坏或变黑
我们的解决方案:
Detection → Is JPEGTABLES present?
│
├─ No → Single-strip: Direct Zero-Copy (0.8ms/page)
│
└─ Yes → Multi-strip: Smart reconstruction
│
├─ First page: Use strip directly (already complete)
│
└─ Subsequent pages: JPEGTABLES + Strip → Decode → FlateDecode
(91.2ms/page, but correct output)这种混合方法实现了 所有页面的正确转换 同时尽可能保持零拷贝性能。
零拷贝架构(基于条带的TIFF)
为什么是脱衣舞? 配备自动文档进纸器(ADF)的高速文档扫描仪将图像作为连续条带写入,以优化连续扫描期间的内存使用。这种“边走边扫描”的方法意味着 整个图像存储在单个条带中 (RowsPerStrip=图像高度),无需重新组装图块即可直接提取流。
| 转换 | 输入大小 | 输出大小 | 页数 | 时间 | 吞吐量 |
|---|---|---|---|---|---|
| PDF→TIFF(条形) | 48 MB | 48 MB | 121 | 63毫秒 | 1920页/秒 |
| TIFF→PDF(条形) | 48 MB | 48 MB | 121 | 86毫秒 | 1407页/秒 |
| TIFF→PDF(JPEG单条) | 8.5 MB | 9.0 MB | 5 | 4ms | 1250页/秒 ⚡ |
| TIFF→PDF(JPEG多条) | 5.3 MB | 7.7 MB | 5 | 456毫秒 | 11页/秒 |
回退模式(平铺TIFF)
为什么平铺的TIFF速度慢: 平铺TIFF将图像存储为独立平铺的网格(例如,256×256像素)。要创建有效的PDF流,所有图块必须 解码→ 重新组装成完整图像→ 重新编码这与PIL、ImageMagick和其他通用图像库使用的处理路径相同,因此根本无法实现零拷贝性能。
| 转换 | 输入大小 | 输出大小 | 页数 | 时间 | 吞吐量 |
|---|---|---|---|---|---|
| TIFF→PDF(平铺33004) | - | 48 MB | 121 | 22秒 | 5.5页/秒 |
性能影响:条形与平铺= 快74倍 (121页,0.3秒对比22秒)
74倍的性能差异不是库的限制,而是 基本建筑差异:
- 基于条带(零拷贝):原始压缩流→ 直接嵌入PDF(无需解码)
- 平铺(后退):解码所有图块→ 重新组装完整图像→ 重编码→ 嵌入(与PIL/ImageMagick相同)
内存使用
| 场景 | 单独包 | 统一包 | 节省 |
|---|---|---|---|
| 闲置 | 40 MB×2=80 MB | 40 MB | 50% |
| 峰值(10个并发) | 160 MB×2=320 MB | 180 MB | 44% |
并发性能
| 请求 | 顺序(同步) | 并行(异步) | 改进 |
|---|---|---|---|
| 1 | 4毫秒 | 4毫秒 | 0% |
| 10 | 40毫秒 | 22毫秒 | 45% |
| 100 | 400毫秒 | 220毫秒 | 45% |
支持格式
📋 压缩格式支持矩阵
具有幂等转换保证的完整往返支持。
| 压缩 | 标记 | TIFF→PDF | PDF→TIFF | 标识 | 注释 |
|---|---|---|---|---|---|
| JPEG格式 7.✅ 零拷贝 | ✅ 零拷贝 | ✅ | 最常见的扫描仪格式 | ||
| JPEG2000 JP2 | 34712 | ✅ 零拷贝 | ✅ 零拷贝 | ✅ | 铅工具 |
| JPEG2000 J2K | 34713 | ✅ 零拷贝 | ✅ 零拷贝 | ✅ | 卡卡杜 |
| JPEG2000库 | 33004 | ✅ 零拷贝 | - | ✅\* | \*标准化为34712 |
| JBIG2 | 34663 | ✅ 零拷贝 | ✅ 零拷贝 | ✅ | 双层(B&W)文件 |
| CCITT集团4 4.✅ 零拷贝 | ✅ 零拷贝 | ✅ | 传真G4压缩 | ||
| CCITT集团3 3.✅ 零拷贝 | ✅ 零拷贝 | ✅ | 传真G3压缩 | ||
| 解压 8.✅ 零拷贝 | ✅ 零拷贝 | ✅ | zlib/ZIP压缩 | ||
| LZW 5.🔄 重新编码 | ✅ 放气 | ✅ | 转换为DEFLATE | ||
| 打包位 | 32773 | 🔄 重新编码 | ✅ 放气 | ✅ | 转换为DEFLATE |
| 未压缩 1.🔄 重新编码 | ✅ 放气 | ✅ | 转换为DEFLATE |
传说:
- ✅ 零拷贝:原始数据传输,无需解码/重新编码(121页约100ms)
- 🔄 重编码:解码并重新压缩为DEFLATE(仍然很快,保持幂等性)
- ✅ 幂等:
TIFF → PDF → TIFF → PDF第一次转换后产生字节相同的输出
JPEG2000标准化(可选)
为了实现文档管道的标准化:
// Enable JPEG2000 normalization
const result = await tiff2pdf.ConvertAsync(tiffPath, pdfPath, {
normalizeJpeg2000: true, // 33004, 34713 → 34712
normalizeFallback: 1 // 0=error, 1=keep original, 2=uncompressed
});
// Result includes normalization statistics
console.log(result.normalizeSuccessCount); // Pages normalized
console.log(result.normalizeFailedCount); // Fallback used| 输入标签 | 输出标签 | 描述 |
|---|---|---|
| 33004(libvips) | 34712(JP2) | 基于平铺→ 条形标准 |
| 34713(J2K) | 34712(JP2) | 码流→ 满JP2集装箱 |
| 34712(JP2) | 34712(JP 2) | 已经是标准配置,没有变化 |
PDF → TIFF转换
从PDF中提取图像并保存为多页TIFF 零拷贝 架构:
| PDF图像过滤器 | TIFF压缩 | 标记 | 性能 | 备注 |
|---|---|---|---|---|
| DCT代码 | JPEG | 7 | ✅ 零拷贝 | 最常见的格式 |
| JPXDecode (JP2) | JPEG2000 JP2 | 34712 | ✅ 零拷贝 | InziSoft格式 |
| JPXDecode (J2K) | JPEG2000 J2K | 34713 | ✅ 零拷贝 | Minervasoft/卡卡杜 |
| JBIG2解码 | JBIG2 | 34663 | ✅ 零拷贝 | 双层图像 |
| CCITTFax解码 | CCITT集团4 | 4 | ✅ 零拷贝 | 传真压缩 |
| CCITTFax解码 | CCITT集团3 | 3 | ✅ 零拷贝 | 传统传真 |
| FlateDecode | 放气 | 8 | ✅ 零拷贝 | zlib压缩 |
特性:
- 需要时自动插入JBIG2文件头(13字节)
- 保留原始压缩(无需重新编码)
- 多页PDF→ 多页TIFF
- 光度解释处理
TIFF → PDF转换
将TIFF图像嵌入到PDF中 自动路径选择 (可能时为零拷贝,必要时重新编码):
| TIFF压缩 | 标记 | PDF过滤器 | 性能 | 备注 |
|---|---|---|---|---|
| CCITT集团3 | 3 | CCITTFaxDecode | ✅ 零拷贝 | 传真压缩,K=0/4 |
| CCITT集团4 | 4 | CCITTFaxDecode | ✅ 零拷贝 | 传真压缩,K=-1 |
| JPEG(单条) | 7 | DCT代码 | ⚡ 零拷贝侦察 | 0.8毫秒/页 -超快! |
| JPEG(多条) | 7 | 平板解码 | 🔄 解码→Deflate | 91.2米/页 -智能回退 |
| 解压 | 8 | 平板解码 | ✅ 零拷贝 | ZIP压缩 |
| JPEG2000(libvips) | 33004 | JPXDecode | ✅ 零拷贝 | libvips编码 |
| JPEG2000(JP2) | 34712 | JPXDecode | ✅ 零拷贝 | InziSoft格式 |
| JPEG2000(J2K) | 34713 | JPXDecode | ✅ 零拷贝 | Minervasoft/卡卡杜 |
| JBIG2 | 34663 | JBIG2解码 | ✅ 零拷贝 | 双层压缩 |
| 未压缩 | 1 | 扁平编码 | 🔄 重新编码 | 解码+解密 |
| CCITT RLE | 2 | 扁平编码 | 🔄 重新编码 | 修改霍夫曼 |
| LZW | 5 | 扁平编码 | 🔄 重新编码 | Lempel Ziv-Welch |
| 打包位 | 32773 | 扁平编码 | 🔄 重新编码 | 苹果RLE |
高级功能:
- 1位双级操控:自动将1位双层图像转换为8位灰度,以兼容PDF
- 色彩空间检测:用途
samples_per_pixel确定/DeviceGray对比/DeviceRGB - CCITT第3组K参数:检测Group3Options标签中的1D/2D编码(K=0/4)
- JPEG颜色转换:从组件ID自动检测(1,2,3 vs 82,71,66)
- 自动MCT检测:解析JPEG2000 COD标记以检测MCT=0/1
- 智能重新编码:将MCT=0流重新编码为MCT=1,以获得适当的显色性
- JP2 IHDR解析:从JP2容器中提取真实维度(修复填充问题)
- JBIG2标头剥离:删除PDF嵌入的13字节文件头
- 光度校正:插入
/Decode [1 0]因为min是黑色的诠释
性能比较
| 操作 | 格式 | 结构 | 时间(121页) | 吞吐量 |
|---|---|---|---|---|
| PDF → TIFF | JPEG/JBIG2 | 基于条带 | 63毫秒 | 1920页/秒 |
| TIFF → PDF | 33004/34713 | 条形 | 86毫秒 | 1407页/秒 |
| TIFF → PDF | 33004 | 平铺128×128 | 22秒 | 5.5页/秒 |
关键洞察:基于条带的布局提供 74倍性能提升 平铺布局
⚡ 性能:74×速度哈克
🚀 实现最佳性能
转换器会自动检测TIFF结构并使用最佳路径:
- 基于条带的TIFF → 零拷贝(推荐,快74倍)
- 平铺TIFF → 解码/重新编码回退(兼容但速度较慢)
⚡ 推荐的TIFF创建设置
为了获得最佳转换性能,请使用以下命令创建TIFF 条形基础 布局:
使用libvips命令行界面
# JPEG2000 J2K format (recommended)
vips tiffsave input.jpg output.tif \
--compression=j2k-minervasoft \
--Q=85 \
--tile=false
# JPEG2000 JP2 format
vips tiffsave input.jpg output.tif \
--compression=jp2-inzisoft \
--Q=85 \
--tile=false使用Python(pyvips)
import pyvips
image = pyvips.Image.new_from_file('input.jpg')
image.tiffsave('output.tif',
compression='j2k-minervasoft', # or 'jp2-inzisoft'
Q=85,
tile=False, # Force strip-based
pyramid=False)使用libtiff
#include
TIFF *tif = TIFFOpen("output.tif", "w");
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_COMPRESSION, 34713); // J2K
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, height); // Full-height strip
// ... write data
TIFFClose(tif);📊 性能比较
基准:121页文档转换(每页816×1056像素)
| TIFF格式 | 结构 | 转换时间 | 性能 |
|---|---|---|---|
| 34713(J2K)条形 | 行/条=高度 | 0.3秒 | ⚡⚡⚡ 最佳 |
| 34712(JP2)条形 | 行/条=高度 | 0.3秒 | ⚡⚡⚡ 最佳 |
| 33004条形 | 行/条=高度 | 0.3秒 | ⚡⚡⚡ 最佳 |
| 33004块瓷砖 | 瓷砖128×128 | 22秒 | 🐌 74倍慢 |
✅ 验证
检查TIFF是否已优化:
tiffinfo your-file.tif | grep -E "(Tile|Rows/Strip)"
# Optimal (strip-based):
# Rows/Strip: 1056 (equals image height)
# Slow (tiled):
# Tile Width: 128 Tile Length: 128💡 对供应商/工具的建议
如果您正在生成用于高容量PDF转换的TIFF:
- 使用基于条带的布局 而不是瓷砖
- 设置行/条=图像高度 (整幅图像为一条)
- 更喜欢压缩34713 (J2K码流)以获得最佳兼容性
- 备选方案:34712 (JP2容器)也支持零拷贝
影响:从平铺模式切换到条形模式 74倍性能提升 没有质量损失。
______________________________________________________________________
🚀 AI研究人员CPU性能指南
为什么CPU很重要:SIMD指令
转换器使用 libjpeg-turbo 对于JPEG再压缩,它利用SIMD(单指令多数据)指令实现了巨大的性能提升。 CPU的指令集直接决定了转换速度。
SIMD技术比较
| 架构 | SIMD技术 | 位宽 | JPEG加速 | 发布年份 |
|---|---|---|---|---|
| ARM (苹果硅) | 霓虹 | 128位 | 3.5× | 2005+ |
| ARM (服务器) | SVE | 128-2048-bit | 4.0×+ | 2017+ |
| x86-64 (英特尔/AMD) | SSE2 | 128位 | 2.8× | 2001+ |
| x86-64 (现代) | AVX2 | 256位 | 4.0× | 2013+ |
| x86-64 (服务器端) | AVX-512 | 512位 | 4.5×+ | 2016+ |
| 传统CPU | 标量(无SIMD) | - | 1.0× | - |
📊 按CPU划分的实际性能(5页TIFF基准)
测试文件: jpeg_5page.tif (5页,高速扫描仪输出)
| CPU型号 | 架构 | SIMD | 时间 | 与ImageMagick的比较 |
|---|---|---|---|---|
| 英特尔至强(AVX-512) | x86-64 | AVX-512 | 110毫秒 | +速度提高68% 🚀 |
| AMD Ryzen 9 7950X | x86-64 | AVX2 | 125毫秒 | +快63% ⚡ |
| 英特尔i9-13900K | x86-64 | AVX2 | 130毫秒 | +速度提高62% ⚡ |
| 英特尔i7-12700K | x86-64 | AVX2 | 140毫秒 | +速度提高59% ⚡ |
| 苹果M3 | ARM64 | 霓虹灯+ | 150毫秒 | +速度提高56% ⚡ |
| 苹果M2 (已测试) | ARM64 | NEON | 164毫秒 | +速度提高52% ✅ |
| 英特尔i5-8400 | x86-64 | AVX2 | 180毫秒 | +速度提高47% |
| 英特尔i3-7100 | x86-64 | SSE2 | 250毫秒 | +速度提高27% |
| ImageMagick(基线) | - | - | 342ms | 基线 |
| Raspberry Pi 4 | ARM64 | NEON | 500毫秒 | 速度提高32% |
| 无SIMD (标量) | - | 无 | 550毫秒 | -慢10% ⚠️ |
🎯 关键见解
- SIMD至关重要:如果没有SIMD支持,性能将降至ImageMagick以下(-10%)
- AVX2推荐:配备AVX2的现代Intel/AMD CPU(2013+)速度提高了60%以上
- 苹果芯片:配备NEON的M1/M2/M3提供52-56%的加速
- 服务器CPU:支持AVX-512的至强实现68%的加速
✅ 如何检查CPU的SIMD支持
macOS(ARM)
sysctl hw.optional.neon
# Output: hw.optional.neon: 1 (✅ NEON supported)Linux(x86-64)
cat /proc/cpuinfo | grep -E "sse2|avx|avx2|avx512"
# Look for: avx2, avx512f窗户(x86-64)
wmic cpu get name
# Then check CPU specs on Intel/AMD website💡 推荐的CPU规格
人工智能研究人员处理大型TIFF数据集:
| 用例 | 推荐CPU | SIMD | 预期性能 |
|---|---|---|---|
| 大批量生产 | AMD 7950X,英特尔i9-13900K | AVX2 | 比ImageMagick快60%以上 |
| 标准工作站 | 英特尔i5-12600K,苹果M2 | AVX2/NEON | 速度快50%以上 |
| 预算/遗产 | 英特尔i3(第7代+) | SSE2 | 快25%以上 |
| 云/服务器 | 英特尔至强(Cascade Lake+) | AVX-512 | 速度提高68%以上 |
📈 性能扩展示例
处理1000万页:
| CPU | 时间 | 成本节约 |
|---|---|---|
| 英特尔i9-13900K(AVX2) | 10.2天 | 基线 |
| 苹果M2(NEON) | 11.5天 | +13%时间 |
| 英特尔i3-7100(SSE2) | 17.8天 | +75%时间 |
| 无SIMD(标量) | 38.5天 | +278%时间⚠️ |
🔧 优化提示
- 使用现代CPU:选择2013+版本的CPU以支持AVX2
- 验证SIMD:确保libjpeg-turbo检测并使用CPU的SIMD
- 多核处理器:批处理受益于高芯数
- 记忆:对于大型TIFF文件(200多页),建议使用16GB+
📊 性能公式
Total Conversion Time = TIFF Decoding + JPEG Recompression + PDF Writing
JPEG Recompression (with SIMD):
- AVX2: ~30ms per page
- NEON: ~40ms per page
- SSE2: ~50ms per page
- No SIMD: ~140ms per page (4.6× slower!)
→ SIMD directly affects 24-40% of total conversion time⚠️ 重要提示
- libjpeg-turbo自动检测:如果您的CPU支持SIMD,则会自动启用它
- 无需配置:该包装开箱即用,效果最佳
- 交叉平台的:SIMD支持适用于Windows、Linux和macOS
- 传统CPU:仍然比ImageMagick快,只是利润率较小
______________________________________________________________________
建筑
项目结构
mcp-janus-converter/
├── package.json
├── README.md
├── LICENSE (MPL 2.0)
├── NOTICE
├── index.js (Unified MCP Server)
├── binding.gyp (Multi-target build)
├── src/
│ ├── pdf2tiff/
│ │ ├── addon.c (N-API wrapper)
│ │ ├── pdf_parser.c (Custom PDF parser)
│ │ ├── pdf_parser.h
│ │ ├── pdf2tiff.c (TIFF generation)
│ │ └── pdf2tiff.h
│ └── tiff2pdf/
│ ├── addon.c (N-API wrapper)
│ ├── tiff_parser.c (TIFF metadata parser)
│ ├── tiff2pdf.c (PDF generation)
│ └── tiff2pdf.h
└── build/Release/
├── pdf2tiff.node
└── tiff2pdf.node多目标构建
这 binding.gyp 配置构建 两个独立的本机插件 来自一个项目:
- pdf2iff.node:PDF→ TIFF转换
- tiff2pdf.node:TIFF→ PDF转换
好处:
- 独立版本控制和更新
- 模块化架构(必要时可单独使用)
- 更容易测试和调试
- 明确区分关注点
异步架构
两个本机插件都使用 N-api异步 具有以下模式:
typedef struct {
napi_async_work work;
napi_deferred deferred;
/* Input parameters */
char source_path[4096];
char target_path[4096];
int verbose;
/* Output results */
int result_code;
int page_count;
char error_message[256];
} ConvertAsyncData;执行流程:
- 主线程:解析参数,创建Promise
- 工作线程 (libuv):执行转换
- 主线程:解决/拒绝Promise
⚖️ 许可证和理念
@janus mcp/converter根据Mozilla公共许可证2.0(MPL 2.0)获得许可。
版权所有(c)2025 Janus项目
这对你意味着什么:
✅ 你可以 在您的商业/专有应用程序中自由使用此软件包。 ✅ 你可以 无需打开应用程序的源代码,即可链接到此包。 ❌ 你不能 修改源文件并将其作为闭源分发。 ❌ 你不能 通过隐藏我们的核心优化来创建“Pro”版本。
为什么选择MPL 2.0?
我们选择此许可证是为了摆脱AGPL(如MuPDF)的限制,同时防止 不道德的供应商利用我们的 零拷贝创新 为了创建锁定, 封闭式衍生品。
“投入就是创新,产出就是授权。” 我们自由分享我们的创新,只要 你尊重核心技术的开放性。
重要通知
看 通知 SDK供应商警告文件。
发展
构建命令
# Clean build
npm run clean
# Build native addons
npm run build
# Rebuild (clean + build)
npm install测试
# Test PDF → TIFF conversion
node -e "
const pdf2tiff = require('./build/Release/pdf2tiff.node');
(async () => {
const result = await pdf2tiff.ConvertAsync('input.pdf', 'output.tif', false);
console.log(result);
})();
"
# Test TIFF → PDF conversion
node -e "
const tiff2pdf = require('./build/Release/tiff2pdf.node');
(async () => {
const result = await tiff2pdf.ConvertAsync('input.tif', 'output.pdf', 0);
console.log(result);
})();
"调试
# Enable verbose output
node index.js --verbose
# Check native addon loading
node -e "
const pdf2tiff = require('./build/Release/pdf2tiff.node');
const tiff2pdf = require('./build/Release/tiff2pdf.node');
console.log('pdf2tiff version:', pdf2tiff.GetVersion());
console.log('tiff2pdf version:', tiff2pdf.GetVersion());
"🚀 与现代浏览器协同(Chrome OCR)
Janus+Chrome=即时OCR和可搜索性
最近,谷歌Chrome浏览器为基于图像的PDF添加了内置的AI OCR。这与Janus形成了强大的协同效应:
- 泛科普特语第11个月-ShortNamePossible 在毫秒内将不可读的专有TIFF转换为标准PDF。
- 铬 打开PDF并自动识别图像中的文本。
- 结果: 你可以 选择、复制和搜索文本 无需在服务器上安装任何繁重的OCR软件,即可从传统扫描文档中读取。
“零服务器负载OCR”:Janus准备文件,Chrome提供情报。
❓ 故障排除/常见问题
Q: 我无法打开TIFF文件。它显示黑屏或错误。
A. 这可能是由于专有的压缩标签。 如果您的TIFF使用以下标签 34712(InziSoft) 或 34713(Minervasoft),标准图像查看器无法解码它们。 Janus解决了这个问题: 它提取隐藏的JPEG2000流并将其封装在标准PDF中,使其在Chrome、Edge或Acrobat中可见。
本机插件构建失败
错误: Cannot find module 'build/Release/pdf2tiff.node'
解决方案:
npm run build未找到libtiff
错误: error while loading shared libraries: libtiff.so.5
背景:Linux预构建是针对Ubuntu 20.04(libtiff.so.5)编译的。较新的发行版使用libtiff.so.6。
libtiff发行版:
| 发行版 | libtiff版本 | SONAME |
|---|---|---|
| Ubuntu 20.04/22.04 | 4.1.0-4.3.0 | libtiff.so.5✅ |
| Ubuntu 24.04+ | 4.5.1+ | libtiff.so.6(需要符号链接) |
| Debian 11(牛眼) | 4.2.0 | libtiff.so.5✅ |
| Debian 12+(书虫) | 4.5.0+ | libtiff.so.6(需要符号链接) |
| RHEL/Rocky/Alma 8.x | 4.0.9 | libtiff.so.5✅ |
| RHEL/Rocky/Alma 9+ | 4.4.0+ | libtiff.so.6(需要符号链接) |
| Fedora 38或更早版本 | 4.4.x | libtiff.so.5✅ |
| Fedora 39+ | 4.5.0+ | libtiff.so.6(需要符号链接) |
libtiff.so.6系统的解决方案 (Ubuntu 24.04、Debian 12、RHEL 9、Fedora 39+):
# 1. Install libtiff if not already installed
sudo apt-get install libtiff-dev # Ubuntu/Debian
# or
sudo dnf install libtiff-devel # RHEL/Fedora
# 2. Find libtiff.so.6 location
find /usr -name "libtiff.so.6*" 2>/dev/null
# Example output: /usr/lib/x86_64-linux-gnu/libtiff.so.6
# 3. Create symlink for libtiff.so.5
sudo ln -s /usr/lib/x86_64-linux-gnu/libtiff.so.6 /usr/lib/x86_64-linux-gnu/libtiff.so.5
# 4. Update library cache
sudo ldconfig
# 5. Verify symlink
ls -la /usr/lib/x86_64-linux-gnu/libtiff.so.5
# Should show: libtiff.so.5 -> libtiff.so.6备选方案(每次会议):
# Set library path without creating system symlink
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH备注:符号链接方法之所以有效,是因为libtiff.so.5和libtiff.so.6与此包使用的函数ABI兼容。
转换失败
错误: Failed to open PDF file 或 Failed to open TIFF file
清单:
- 验证输入文件是否存在并且可读
- 检查文件权限
- 确保文件路径是绝对路径或正确的相对路径
- 验证文件格式(未损坏)
贡献
我们欢迎捐款!请阅读我们的 贡献指南 在提交pull请求之前。
开发流程
- 分叉存储库
- 创建要素分支(
git checkout -b feature/amazing-feature) - 进行更改
- 用常规承诺进行承诺(
git commit -m "feat: add amazing feature") - 推到您的分支(
git push origin feature/amazing-feature) - 打开拉取请求
路线图
- \[x\] v1.0.0:Windows x64预构建二进制文件
- \[x\] v1.1.0版本:Linux x64预构建二进制文件(Ubuntu 20.04+,glibc 2.31+)
- \[x\] v1.2.0版本:macOS ARM预构建二进制文件
- \[x\] v1.3.0版本:零拷贝JPEG优化(单条加快493倍,多条加快4.3倍)
- \[ \] v1.4.0版本:高级PDF元数据提取
- \[ \] v1.5.0:TIFF注释渲染
- \[ \] v2.0.0版本:支持其他压缩格式
学分
- libvips:需求驱动的图像处理库
- LibTiff:TIFF读/写库
- OpenJPEG:JPEG 2000编解码器库
- MCP-SDK:Anthropic的模型上下文协议
支持
- 问题:
- 讨论:
- 电子邮件: tangokorea@gmail.com
许可证
此项目根据Mozilla公共许可证2.0获得许可-请参阅 许可证 文件以获取详细信息。
______________________________________________________________________
制作❤️ Janus项目
