Apache Batik 常用 CLI 命令与工具详解
详解 Apache Batik 1.19 五个命令行工具:rasterizer 光栅化、svgpp 格式化、ttf2svg 字体转换与 squiggle/slideshow,含 usage 回显、批量转换退出码陷阱与无显示环境排障实测。
Apache Batik 常用 CLI 命令与工具详解
目标:把 Apache Batik 1.19 发行包自带的 5 个命令行工具一次讲透——rasterizer 批量光栅化、svgpp 源码格式化、ttf2svg 字体转换、squiggle SVG 浏览器、slideshow 图片轮播——每个工具给出完整 usage 回显、真实参数默认值、可复现的转换实测,并重点澄清批量转换「失败不中断、退出码仍为 0」的运维陷阱,已在 Ubuntu 22.04(OpenJDK 17.0.20.1)实测通过。
一、环境信息
本篇所有命令与回显均在以下环境中实测采集:
- 操作系统:Ubuntu 22.04.5 LTS,x86_64
- JDK:OpenJDK 17.0.20.1(
openjdk-17-jdk-headless) - 组件版本:Apache Batik 1.19(官方 batik-bin-1.19.tar.gz 发行包,14165777 字节,sha512 校验通过)
- 发行包目录:
/opt/batik(5 个应用 jar + lib/ 模块 jar) - 实验目录:
/opt/lab/cli(测试 SVG 与产物) - 执行用户:root
二、工具概览
发行包顶层自带 5 个应用 jar,覆盖从转换、格式化到浏览、放映的场景:
| 工具 | 应用 jar | 类型 | 用途 |
|---|---|---|---|
| rasterizer | batik-rasterizer-1.19.jar | 命令行 | SVG 批量转 PNG/JPEG/TIFF 光栅图 |
| svgpp | batik-svgpp-1.19.jar | 命令行 | SVG 源码格式化、DOCTYPE/换行符处理 |
| ttf2svg | batik-ttf2svg-1.19.jar | 命令行 | TrueType 字体转 SVG 内嵌字体 |
| squiggle | batik-squiggle-1.19.jar | 图形界面 | Swing SVG 浏览器 |
| slideshow | batik-slideshow-1.19.jar | 图形界面 | 图片轮播放映 |
三个实测事实先交代清楚:发行包不含任何 shell 启动脚本(tar -tzf batik-bin-1.19.tar.gz | grep -c "\.sh" 实测为 0),所有工具一律 java -jar 启动;各工具共享 lib/ 下的模块 jar,挪走应用 jar 会破坏类路径;README 要求 Java 8+,本篇全部在 OpenJDK 17 下实测(Java 8 亦可运行,仅少 4 行 SecurityManager 弃用 WARNING)。
三、前置条件
从零准备发行包与测试文件。下载、校验、解压一条命令完成:
mkdir -p /opt/lab && cd /opt/lab && wget -q https://dlcdn.apache.org/xmlgraphics/batik/binaries/batik-bin-1.19.tar.gz && wget -q https://dlcdn.apache.org/xmlgraphics/batik/binaries/batik-bin-1.19.tar.gz.sha512 && sha512sum -c batik-bin-1.19.tar.gz.sha512 && tar xzf batik-bin-1.19.tar.gz -C /opt
回显(实测):
batik-bin-1.19.tar.gz: OK
⚠️ 注意:下载路径是
dlcdn.apache.org/xmlgraphics/batik/binaries/,旧资料里的downloads.apache.org/batik/与archive.apache.org/dist/batik/实测均已 404。
确认 5 个应用 jar 就位:
ls /opt/batik/*.jar
回显(实测):
/opt/batik/batik-rasterizer-1.19.jar
/opt/batik/batik-slideshow-1.19.jar
/opt/batik/batik-squiggle-1.19.jar
/opt/batik/batik-svgpp-1.19.jar
/opt/batik/batik-ttf2svg-1.19.jar
准备两个测试文件(rasterizer 用 400x200 的 hello.svg,svgpp 用单行压缩的 messy.svg):
mkdir -p /opt/lab/cli && cat > /opt/lab/svg/hello.svg << "SVGEOF"
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 200">
<rect x="0" y="0" width="400" height="200" fill="#1e88e5"/>
<circle cx="80" cy="100" r="50" fill="#ffca28"/>
<text x="150" y="110" font-family="DejaVu Sans" font-size="32" fill="#ffffff">Hello Batik</text>
</svg>
SVGEOF
printf "%s" "<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"120\" height=\"60\"><rect x=\"1\" y=\"2\" width=\"118\" height=\"58\" fill=\"#2e7d32\"/><text x=\"10\" y=\"38\" font-size=\"14\" fill=\"#fff\">cli</text></svg>" > /opt/lab/cli/messy.svg
回显(实测,写入成功无输出):
ttf2svg 实测还需要一个 TrueType 字体,Ubuntu 自带 DejaVu 系列(无则 apt-get install -y fonts-dejavu-core):
ls -l /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf | awk '{print $5, $9}'
回显(实测):
757076 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
四、rasterizer:SVG 转 PNG/JPEG/TIFF 光栅化
rasterizer 是 Batik 使用频率最高的工具。它没有 -help 选项——无参运行就是帮助,选项表走 stdout(stderr 上是 JDK 17 的 4 行 SecurityManager 弃用 WARNING,用 2>/dev/null 隔离):
java -jar /opt/batik/batik-rasterizer-1.19.jar 2>/dev/null | head -8
输出节选(实测首部):
SVG Rasterizer options are:
-d <dir|file>
output directory. If there is a single input file, this can be a file.
-m <mimeType>
output mime type.
-w <width>
output width. This is a floating point value.
完整选项共 22 个(-d/-m/-w/-h/-maxw/-maxh/-a/-bg/-cssMedia/-cssAlternate/-cssUser/-font-family/-lang/-q/-indexed/-dpi/-validate/-onload/-snapshotTime/-scriptSecurityOff/-anyScriptOrigin/-scripts),逐参数语义与默认值见《Apache Batik 配置参数详解》第四章。若误传 -help,它会被当成待转换文件名而报错:
java -jar /opt/batik/batik-rasterizer-1.19.jar -help 2>/dev/null | head -1
输出节选(实测首部):
Error while converting files: Error: no output directory specified and source is not a file (source causing failure is "file:-help"
4.1 单文件转换与三种输出格式
不带任何参数转换,输出 PNG 落在源文件旁边:
java -jar /opt/batik/batik-rasterizer-1.19.jar /opt/lab/svg/hello.svg
输出节选(实测):
Converting hello.svg to /opt/lab/svg/hello.png ... ... success
用 PNG 魔数与 IHDR 块验证产物真实性(前 8 字节应为 89 50 4e 47 0d 0a 1a 0a):
od -An -tx1 -N8 /opt/lab/svg/hello.png && ls -l /opt/lab/svg/hello.png | awk '{print $5}'
回显(实测):
89 50 4e 47 0d 0a 1a 0a
5870
-m 指定 MIME 类型切换格式,-d 指定输出位置:
java -jar /opt/batik/batik-rasterizer-1.19.jar -m image/jpeg -q 0.8 -w 800 -d /opt/lab/out /opt/lab/svg/hello.svg
java -jar /opt/batik/batik-rasterizer-1.19.jar -m image/tiff -d /opt/lab/out /opt/lab/svg/hello.svg
ls -l /opt/lab/out/hello.jpg /opt/lab/out/hello.tif | awk '{print $5, $9}'
回显(实测):
Converting hello.svg to /opt/lab/out/hello.jpg ... ... success
Converting hello.svg to /opt/lab/out/hello.tif ... ... success
13749 /opt/lab/out/hello.jpg
320440 /opt/lab/out/hello.tif
💡 技术拓展:三种输出格式怎么选——
格式 MIME 透明通道 质量参数 典型场景 PNG image/png 有 无(无损) 图标、需要透明的素材,可配 -indexed 压体积 JPEG image/jpeg 无(用 -bg 垫底色) -q 仅对此格式有效 照片类大图、体积敏感 TIFF image/tiff 有 无 归档、印刷链路;扩展名固定 .tif 不是 .tiff;1.19 默认不压缩(400x200 实测 320440B,同源 PNG 仅 5870B),慎用于批量
4.2 尺寸与质量控制
-w/-h 直接设定输出像素尺寸,用 IHDR 块复核(第 16~23 字节为宽高大端整数):
java -jar /opt/batik/batik-rasterizer-1.19.jar -w 800 -h 400 -d /opt/lab/out-wh /opt/lab/svg/hello.svg 2>/dev/null
od -An -tu1 -j16 -N8 /opt/lab/out-wh/hello.png
回显(实测):
0 0 3 32 0 0 1 144
前三字节 0x0320=800、后四字节 0x0190=400,精确生效。-maxw 200 则把 400x200 等比缩到 200x100(只给上限、保持纵横比)。JPEG 质量用同一源做梯度对比:
ls -l /opt/lab/out/jq/hello.jpg /opt/lab/out/jq80/hello.jpg /opt/lab/out/jq30/hello.jpg | awk '{print $5, $9}'
回显(实测):
5050 /opt/lab/out/jq/hello.jpg
5486 /opt/lab/out/jq80/hello.jpg
3380 /opt/lab/out/jq30/hello.jpg
不带 -q 时 Batik 不设置质量提示、走 ImageIO 默认编码(5050B 反而小于 -q 0.8 的 5486B),显式给 -q 才按给定质量编码。-q 的越界行为实测——传 -q 1:
java -jar /opt/batik/batik-rasterizer-1.19.jar -m image/jpeg -q 1 -d /opt/lab/out /opt/lab/svg/hello.svg 2>/dev/null | tail -5
回显(实测收尾段):
Error: illegal argument for option -q : 1
-q <quality> Quality for the generated output image. This is only used for JPEG conversion.
The value should be in the [0,1] range.
Example: -q 0.5
Default: 0.99
官方文案标注默认 0.99、声称 [0,1],但实测 1 本身被拒,实际可用区间是开区间 0 < q < 1。PNG 侧的体积开关是 -indexed 8(256 色自适应调色板):同一源全彩 5870B,索引色 3544B,省约 40% 体积。
4.3 批量转换:多文件与整目录
rasterizer 原生支持批量。多文件方式(一次传多个源文件):
mkdir -p /opt/lab/cli/batch && cp /opt/batik/samples/asf-logo.svg /opt/batik/samples/batikBatik.svg /opt/batik/samples/barChart.svg /opt/lab/cli/batch/ && java -jar /opt/batik/batik-rasterizer-1.19.jar -d /opt/lab/cli/batch/out1 /opt/lab/cli/batch/asf-logo.svg /opt/lab/cli/batch/batikBatik.svg /opt/lab/cli/batch/barChart.svg 2>/dev/null | grep -E "About to transcode|Converting|error"
输出节选(实测):
About to transcode 3 SVG file(s)
Converting asf-logo.svg to /opt/lab/cli/batch/out1/asf-logo.png ... ... success
Converting batikBatik.svg to /opt/lab/cli/batch/out1/batikBatik.png ... ... success
Converting barChart.svg to /opt/lab/cli/batch/out1/barChart.png ... org.w3c.dom.DOMException: file:/opt/lab/cli/batch/tests/resources/style/test.css:
Invalid CSS document.
... error (SVGConverter.error.while.rasterizing.file)
整目录方式(源参数直接给目录,转换其中全部 SVG):
mkdir -p /opt/lab/cli/dirsrc && cp /opt/lab/svg/hello.svg /opt/lab/cli/messy.svg /opt/lab/cli/dirsrc/ && java -jar /opt/batik/batik-rasterizer-1.19.jar -d /opt/lab/cli/dirout /opt/lab/cli/dirsrc 2>/dev/null | grep -E "About to transcode|Converting"
回显(实测):
About to transcode 2 SVG file(s)
Converting messy.svg to /opt/lab/cli/dirout/messy.png ... ... success
Converting hello.svg to /opt/lab/cli/dirout/hello.png ... ... success
上面多文件批处理暴露了两个必须知道的运维事实。其一,barChart.svg 失败的原因是它引用了相对路径资源(tests/resources/style/test.css 样式表与 batikLogo.svg 的 <use> 引用),被复制出 samples 目录后路径断了——带相对引用的 SVG 必须在原目录内转换,或连同依赖一并复制。其二,失败文件不中断批处理,且进程退出码仍为 0(重定向到日志后 echo $? 实测为 0),产物目录里甚至留下一个 0 字节的 barChart.png。因此脚本化批量时不能只看退出码,必须清点 success 行数:
java -jar /opt/batik/batik-rasterizer-1.19.jar -d /opt/lab/cli/batch/out2 /opt/lab/cli/batch/asf-logo.svg /opt/lab/cli/batch/batikBatik.svg /opt/lab/cli/batch/barChart.svg > /tmp/batch.log 2>&1
echo "exit=$?"; grep -c "... success" /tmp/batch.log; ls -l /opt/lab/cli/batch/out2/ | awk '{print $5, $9}'
回显(实测):
exit=0
2
13932 /opt/lab/cli/batch/out2/asf-logo.png
0 /opt/lab/cli/batch/out2/barChart.png
236854 /opt/lab/cli/batch/out2/batikBatik.png
输入 3 个、success 只有 2 行、退出码却是 0——判断批处理成败的唯一可靠依据是 success 行数与输入数一致,并对 0 字节产物做清理或告警。
4.4 脚本执行与安全沙箱(-onload)
-onload 让 rasterizer 在派发 onload 事件后再光栅化(SVG 内嵌 ECMAScript 才会执行),它受安全沙箱约束。1.19 的实测链路有三层:java -jar 方式直接报 NoClassDefFoundError: org/mozilla/javascript/WrapFactory(rasterizer 的 MANIFEST Class-Path 未引用 lib/ 自带的 rhino-1.7.7.jar);改用主类方式 java -cp "batik-rasterizer-1.19.jar:lib/*" org.apache.batik.apps.rasterizer.Main 后脚本引擎初始化被沙箱拦截(AccessControlException: access denied ("java.util.PropertyPermission" "rhino.stack.style" "read"),内置策略白名单写的 lib/js.jar 与实捆 rhino-1.7.7.jar 文件名不匹配);加 -scriptSecurityOff 关沙箱后渲染流程走完,但 Batik 全局包装脚本与 Rhino 全系不兼容(Function importClass must be called with a class),onload 实际未生效、产物哈希与静态渲染完全一致。逐条命令与完整回显见《Apache Batik 配置参数详解》第七章,生产建议:以 Transcoder API 静态渲染为主,不依赖 -onload。
五、svgpp:SVG 源码格式化
svgpp 是 SVG 源码的 pretty-printer:把压缩成单行的 SVG 重新缩进排版,顺带处理 DOCTYPE、换行符与 XML 声明。无参运行输出用法:
java -jar /opt/batik/batik-svgpp-1.19.jar 2>/dev/null
回显(实测全文):
SVG pretty-printer - (C) Apache Software Foundation
http://xmlgraphics.apache.org/batik
Syntax:
svgpp [options] <input file> [<output file>]
Available Options:
-doctype (change | remove)
Removes or changes the DOCTYPE declaration. change is used
in conjonction with the -public-id and -system-id options.
-doc-width <number>
Sets the document preferred number of columns. The default is 80.
-public-id <string>
The value to set to the public ID of the doctype.
-system-id <string>
The value to set to the system ID of the doctype.
-tab-width <number>
Sets the tabulation width. The default is 4.
-newline (cr | cr-lf | lf)
Specifies the type of newline to output. Possible values are:
cr (mac), cr-lf (dos), lf (unix - the default).
-no-format
Disables any formatting. Useful for doctype modifications,
newline conversion, ...
-xml-decl <string>
The value to set to the XML declaraction.
注意两个参数不是布尔开关而是带值选项:-doc-width(每行目标列数,默认 80)与 -tab-width(缩进空格数,默认 4);-newline 默认 lf。
5.1 格式化实测
把前置条件里 223 字节的单行 messy.svg 以 60 列宽度格式化输出:
java -jar /opt/batik/batik-svgpp-1.19.jar -doc-width 60 -newline lf /opt/lab/cli/messy.svg /opt/lab/cli/pretty.svg
echo "exit=$?"
cat /opt/lab/cli/pretty.svg
回显(实测):
exit=0
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="120"
height="60">
<rect x="1" y="2" width="118" height="58" fill="#2e7d32"/>
<text x="10" y="38" font-size="14" fill="#fff">
cli
</text>
</svg>
效果符合 -doc-width 60 的预期:原本单行的 <svg ...> 标签在 60 列处断行、属性缩进对齐;产物 254 字节。svgpp 只动排版不改语义——对格式化产物再做一次光栅化,尺寸与内容应与源文件产物一致,这是最简单的验证方式:
java -jar /opt/batik/batik-rasterizer-1.19.jar -d /opt/lab/cli/ppcheck /opt/lab/cli/pretty.svg 2>/dev/null && od -An -tu1 -j16 -N8 /opt/lab/cli/ppcheck/pretty.png
回显(实测):
0 0 0 120 0 0 0 60
IHDR 显示 120x60,与源文件声明一致。
5.2 DOCTYPE 与换行符处理
svgpp 的另两族参数面向流水线场景:-doctype remove 去掉 DOCTYPE 声明(配合 -no-format 可做「只改 DOCTYPE、不动排版」的纯转换),-doctype change 配合 -public-id/-system-id 改写声明指向;-newline cr-lf 把文件转成 DOS 换行(产物用 file 命令可见 CRLF line terminators);-xml-decl "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" 可整条替换 XML 声明。这些参数组合的取舍:规范化存量 SVG 库时先 -doctype remove -newline lf 统一形态,再入库版本管理。
六、ttf2svg:TrueType 字体转 SVG 字体
ttf2svg 把 TTF 字体转成 SVG Font 格式,让 SVG 在不安装字体的环境下内嵌渲染文本。无参运行输出用法:
java -jar /opt/batik/batik-ttf2svg-1.19.jar 2>/dev/null
回显(实测全文):
usage: java org.apache.batik.svggen.font.SVGFont <ttf-path> [-l <range-begin>] [-h <range-end>] [-autorange] [-ascii] [-id <id>] [-o <output-path>] [-testcard]
单行 usage,参数含义:-l/-h 限定码位区间(十进制 Unicode 起止),-autorange 全量导出,-ascii 只导 ASCII 区(65~90 即 A-Z),-id 指定 font id,-o 输出路径,-testcard 生成字形自检页。
6.1 转换实测
把 DejaVuSans 的大写字母区(码位 65~90)转成 SVG 字体:
java -jar /opt/batik/batik-ttf2svg-1.19.jar /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf -l 65 -h 90 -id DejaVuSans -o /opt/lab/cli/DejaVu.svg
echo "exit=$?"
ls -l /opt/lab/cli/DejaVu.svg | awk '{print $5}'
head -c 340 /opt/lab/cli/DejaVu.svg
回显(实测):
exit=0
7512
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" > <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<defs >
<font id="DejaVuSans" horiz-adv-x="1038" ><font-face
font-family="DejaVu Sans"
units-per-em="2048"
panose-1="2 11 6 3 3 8 4 2 2 4"
ascent="1901"
descent="-483
产物结构解读:外层 <defs> 下的 <font> 元素携带 font-face(字族名 DejaVu Sans、units-per-em 2048、ascender/descender 度量)与逐字形的 <glyph> 路径数据。使用方式是把该文件以 <use> 或合并进目标 SVG 的 <defs>,文本用 font-family="DejaVu Sans" 即可命中内嵌字形——这正是服务器侧「无字体环境渲染带文字 SVG」的标准解法。
💡 技术拓展:SVG 内嵌字体与常见替代方案的取舍——
方案 载体 优点 局限 SVG Font(ttf2svg 产物) SVG 文件内 <font>零外部依赖、随 SVG 走 只对引用它的 SVG 生效,字形多时体积大 系统安装字体 操作系统字体目录 渲染质量最佳 每台机器都要装,多机环境逐台分发麻烦 Web 字体(@font-face) WOFF/TTF 文件 浏览器生态成熟 Batik 渲染 SVG 时不走浏览器字体栈 服务端批量光栅化场景优先级:能装字体就装字体(一次装机全局生效),不可控环境才用 ttf2svg 内嵌。
6.2 字符区间选择的两个实用组合
-l 65 -h 90(A-Z 大写区)适合图标类 SVG 的少量英文标注,实测产物 7512 字节;-ascii 等价于 -l 0 -h 127 覆盖全部 ASCII;全量导出用 -autorange(DejaVuSans 全字库会生成数十 MB 的 SVG,仅在确需生僻字形时使用)。区间值是十进制 Unicode 码位,中文常用区(如 19968 起的 CJK 统一表意区)同样适用,但务必先评估产物体积。
七、squiggle:SVG 浏览器
squiggle 是 Batik 自带的 Swing SVG 浏览器,支持脚本、动画与缩放。无显示环境直接启动必然失败:
java -jar /opt/batik/batik-squiggle-1.19.jar 2>&1 | grep -A4 "HeadlessException" | head -5
输出节选(实测):
java.awt.HeadlessException:
No X11 DISPLAY variable was set,
or no headful library support was found,
but this program performed an operation which requires it.
服务器上体验 squiggle 的标准做法是 Xvfb 虚拟显示。安装 X 组件(xvfb 提供虚拟 X server,其余四个库补齐 headful 本地支持):
apt-get install -y xvfb libxext6 libxrender1 libxtst6 libxi6 > /dev/null 2>&1
echo "install-exit=$?"
回显(实测):
install-exit=0
启动虚拟显示与浏览器(JVM 堆显式限制在 256MB):
Xvfb :99 -screen 0 1280x800x24 &
sleep 1
DISPLAY=:99 java -Xms256m -Xmx256m -jar /opt/batik/batik-squiggle-1.19.jar > /tmp/squiggle.log 2>&1 &
sleep 8
jps -v | grep squiggle
回显(实测):
5782 batik-squiggle-1.19.jar -Xms256m -Xmx256m
jps -v 能看到进程带着 -Xms256m -Xmx256m 参数在跑,日志里仅有 4 行 SecurityManager 弃用 WARNING、无异常栈,说明浏览器已在虚拟显示下正常启动(窗口交互需 VNC 等远程桌面配合,服务器场景一般只用于验证 SVG 能否被 Batik 完整解析渲染)。squiggle 的脚本安全设置与 rasterizer 同源:同受内置策略资源约束,菜单内可调整脚本加载策略,偏好持久化走 JVM 标准的 java.util.prefs 机制。
八、slideshow:图片轮播
slideshow 把一组图片以全屏轮播+过渡动画放映,定位是「光栅化产物的放映器」。无参运行输出参数表:
java -jar /opt/batik/batik-slideshow-1.19.jar 2>/dev/null
回显(实测全文):
Options:
-- : Remaining args are file names
-fl <file>
--file-list <file> : file contains list of images to
show one per line
-ws <width>[,<height>]
-window-size <width>[,<height>] : Set the size of slideshow window
defaults to full screen
-ft <int>
--frame-time <int> : Amount of time in millisecs to
show each frame.
Includes transition time.
三组参数:-fl 指定图片清单文件(每行一个文件路径);-ws 设定窗口尺寸(默认全屏);-ft 设定每帧停留毫秒数(含过渡时间)。图片既可写在命令行剩余参数里,也可用 -- 分隔后列出。与 squiggle 一样依赖图形环境,无显示下给定图片文件启动即失败且退出码为 1:
java -jar /opt/batik/batik-slideshow-1.19.jar /opt/lab/svg/hello.png > /tmp/ss.log 2>&1
echo "exit=$?"
grep -A2 "HeadlessException" /tmp/ss.log | head -3
回显(实测):
exit=1
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set,
or no headful library support was found,
需要实际放映时,按第七章方式先起 Xvfb,再 DISPLAY=:99 java -jar batik-slideshow-1.19.jar -ft 3000 -fl /tmp/list.txt 即可。slideshow 只接受位图清单,SVG 要先经 rasterizer 转换。
九、注意事项
- rasterizer 的帮助是无参运行,
-help会被当成输入文件名报错;其余工具(svgpp/slideshow)无参输出用法、ttf2svg 无参输出单行 usage,行为不一致但都不支持-h/--help。 - 批量转换退出码恒为 0(实测含失败文件也是 0),脚本化时必须
grep -c "... success"清点成功数并与输入数比对;失败文件会留下 0 字节产物,需清理。 - 相对引用资源要完整:samples 中带外部 CSS(xml-stylesheet 处理指令)或
<use xlink:href="batikLogo.svg">引用的 SVG,脱离原目录转换会报 Invalid CSS document 或 No such file or directory。 - JDK 17 下每次启动输出 4 行
System::setSecurityManager弃用 WARNING,来自 Batik 安装脚本沙箱的固定行为,非故障;Java 8 运行无此输出。 - JPEG 专属参数勿用于 PNG:
-q只对 image/jpeg 生效(取开区间 0<q<1,官方文案默认 0.99);-indexed只对 PNG 生效;TIFF 的输出扩展名固定是.tif。 - 批量任务给足堆内存:单机大批量建议
java -Xms256m -Xmx512m -jar batik-rasterizer-1.19.jar ...启动,启动后用jps -v核对参数已生效;单文件小图转换默认堆即可。 - 图形界面工具(squiggle/slideshow)在服务器上必须先有 X 显示(Xvfb 即可)并补齐 headful 库,否则一律 HeadlessException。
十、常见问题(FAQ)
Q1:java -jar batik-rasterizer-1.19.jar -help 为什么报「source is not a file (source causing failure is "file:-help"」?
rasterizer 没有 -help 选项,所有 - 开头的未知参数都被当作输入源解析。看帮助的正确方式是无参运行(见第四章开头)。
Q2:批量转换怎么判断全部成功?进程退出码是 0 但明明有文件失败。
rasterizer 对单文件失败只打 error 日志、不中断批处理、不影响退出码(实测含失败文件时 echo $? 仍为 0)。可靠做法:输出重定向到日志后 grep -c "... success" 日志文件,行数等于输入数才算全成;同时检查产物目录无 0 字节文件。
Q3:转换官方 samples 里的 SVG 报 Invalid CSS document 或 batikLogo.svg 不存在? 这些 SVG 引用了相对路径的外部资源(如 barChart.svg 引用 tests/resources/style/test.css 与 batikLogo.svg)。把文件复制走再转换就会断链——在 samples 原目录内原地转换,或连同全部被引用资源保持相对结构复制。
Q4:-q 1 为什么抛 IllegalArgumentException?文案不是说 [0,1] 吗?
实测 1 越界被拒,实际可用区间是开区间 0<q<1;错误文案自带说明(Example: -q 0.5 / Default: 0.99)。JPEG 想要最高质量用 -q 0.99。
Q5:squiggle/slideshow 启动抛 HeadlessException 怎么解决?
两步:apt-get install -y xvfb libxext6 libxrender1 libxtst6 libxi6 补图形栈,然后 Xvfb :99 -screen 0 1280x800x24 & 起虚拟显示,启动时加 DISPLAY=:99 前缀(squiggle 完整实测见第七章)。
Q6:ttf2svg 转出来的 SVG 字体怎么在别的 SVG 里用?
把产物内容(外层 <defs> 整块)合并进目标 SVG 的 <defs>,文本元素的 font-family 写成 font-face 声明的字族名(实测产物为 DejaVu Sans)即可命中内嵌字形;也可将产物独立保存后用 <use> 引入。注意只导出需要的码位区间控制体积。
十一、参考链接
- 官方 Rasterizer 工具文档:https://xmlgraphics.apache.org/batik/tools/rasterizer.html
- 官方 SVG Pretty Printer(svgpp)文档:https://xmlgraphics.apache.org/batik/tools/pretty-printer.html
- 官方字体转换器(ttf2svg)文档:https://xmlgraphics.apache.org/batik/tools/font-converter.html
- 官方 SVG 浏览器(squiggle)文档:https://xmlgraphics.apache.org/batik/tools/browser.html
- 发行包下载目录:https://dlcdn.apache.org/xmlgraphics/batik/binaries/