Apache Batik 常用 CLI 命令与工具详解

详解 Apache Batik 1.19 五个命令行工具:rasterizer 光栅化、svgpp 格式化、ttf2svg 字体转换与 squiggle/slideshow,含 usage 回显、批量转换退出码陷阱与无显示环境排障实测。

Apache BatikBatik2026/10/13

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类型用途
rasterizerbatik-rasterizer-1.19.jar命令行SVG 批量转 PNG/JPEG/TIFF 光栅图
svgppbatik-svgpp-1.19.jar命令行SVG 源码格式化、DOCTYPE/换行符处理
ttf2svgbatik-ttf2svg-1.19.jar命令行TrueType 字体转 SVG 内嵌字体
squigglebatik-squiggle-1.19.jar图形界面Swing SVG 浏览器
slideshowbatik-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透明通道质量参数典型场景
PNGimage/png有无(无损)图标、需要透明的素材,可配 -indexed 压体积
JPEGimage/jpeg无(用 -bg 垫底色)-q 仅对此格式有效照片类大图、体积敏感
TIFFimage/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 转换。

九、注意事项

  1. rasterizer 的帮助是无参运行,-help 会被当成输入文件名报错;其余工具(svgpp/slideshow)无参输出用法、ttf2svg 无参输出单行 usage,行为不一致但都不支持 -h/--help。
  2. 批量转换退出码恒为 0(实测含失败文件也是 0),脚本化时必须 grep -c "... success" 清点成功数并与输入数比对;失败文件会留下 0 字节产物,需清理。
  3. 相对引用资源要完整:samples 中带外部 CSS(xml-stylesheet 处理指令)或 <use xlink:href="batikLogo.svg"> 引用的 SVG,脱离原目录转换会报 Invalid CSS document 或 No such file or directory。
  4. JDK 17 下每次启动输出 4 行 System::setSecurityManager 弃用 WARNING,来自 Batik 安装脚本沙箱的固定行为,非故障;Java 8 运行无此输出。
  5. JPEG 专属参数勿用于 PNG:-q 只对 image/jpeg 生效(取开区间 0<q<1,官方文案默认 0.99);-indexed 只对 PNG 生效;TIFF 的输出扩展名固定是 .tif。
  6. 批量任务给足堆内存:单机大批量建议 java -Xms256m -Xmx512m -jar batik-rasterizer-1.19.jar ... 启动,启动后用 jps -v 核对参数已生效;单文件小图转换默认堆即可。
  7. 图形界面工具(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> 引入。注意只导出需要的码位区间控制体积。

十一、参考链接