Apache Batik 配置参数详解

梳理 Apache Batik 1.19 全部配置入口:rasterizer 命令行参数与真实默认值、Transcoder 提示键、解析器系统属性、脚本安全沙箱与策略资源、Squiggle 偏好,逐项实测并给出光栅化服务推荐参数集。

Apache BatikBatik2026/10/13

Apache Batik 配置参数详解

目标:把 Apache Batik 1.19 的全部配置入口一次讲清——命令行参数与真实默认值、Transcoder 提示键、解析器系统属性、脚本安全沙箱与策略资源、Squiggle 偏好存储,每项配置都配实测命令与回显,并在文末给出光栅化服务的推荐参数集,已在 Ubuntu 22.04(OpenJDK 17.0.20.1)与 CentOS 8.4(OpenJDK 8/17)双环境实测通过。

一、环境信息

本篇所有命令与回显均在以下环境中实测采集:

  • 操作系统:Ubuntu 22.04.5 LTS(主环境)、CentOS 8.4.2105(对照环境),x86_64
  • JDK:OpenJDK 17.0.20.1(Ubuntu)/ OpenJDK 1.8.0_312 与 17.0.1(CentOS)
  • 组件版本:Apache Batik 1.19(官方 batik-bin 发行包 + Maven org.apache.xmlgraphics:batik-transcoder 1.19)
  • 实验目录:/opt/batik(发行包根)、/opt/lab(测试文件)
  • 执行用户:root

二、前置条件

本篇示例直接复用发行包与一个最小 Maven/手动工程;若从零开始,先完成发行包解压:

java -jar /opt/batik/batik-rasterizer-1.19.jar 2>&1 | head -3

输出节选(实测首部,JDK 17 下含 4 行 WARNING,此处节选选项表开头):

SVG Rasterizer options are:
 -d <dir|file>
        output directory. If there is a single input file, this can be a file.

工具可用即说明环境就绪。测试 SVG(/opt/lab/hello.svg,400x200):

cat > /opt/lab/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

回显(实测,写入成功无输出):

三、配置体系总览

先厘清「Batik 从哪里读配置」。实测对发行包全部 jar 做字节检索:

cd /opt/batik/lib && for j in *.jar; do unzip -p $j 2>/dev/null | grep -qa "batik.properties" && echo "FOUND $j"; done

回显(实测,全部 jar 无命中):

结论:Batik 1.19 不存在名为 batik.properties 的用户配置文件(旧资料偶有提及,请勿照找)。1.19 的真实配置入口共四类,本篇逐类详解:

入口载体生效范围
命令行参数rasterizer/svgpp/ttf2svg 的选项单次调用
Transcoder 提示键addTranscodingHint(KEY_*, value)单次 API 调用
系统属性org.xml.sax.driver、org.w3c.css.sac.driver 等,java -D 注入JVM 进程级
安全策略资源jar 内 rasterizer.policy/svgbrowser.policy 策略文件脚本沙箱

另外 Squiggle 浏览器的界面偏好通过 JVM 标准的 java.util.prefs 持久化(见第八章)。

四、命令行参数详解(rasterizer)

rasterizer 是最常用的转换入口,先取完整选项表作为参数清单基准(实测无参运行输出,逐行照抄):

java -jar /opt/batik/batik-rasterizer-1.19.jar

回显(实测全文,已剔除 JDK 17 的 4 行 WARNING):

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.
 -h <height>
        output height. This is a floating point value.
 -maxw <width>
        Maximum output width. This is a floating point value.
 -maxh <height>
        Maximum output height. This is a floating point value.
 -a <area>
        output area. The format for <area> is x,y,w,h, where x, y, w and h
        are floating point values.
 -bg <color>
        ouput color. The format for <color> is a.r.g.b, where a, r, g and b
        are integer values.
 -cssMedia <media>
        CSS media type for which the source SVG files should be
        converted.
 -cssAlternate <alternate>
        CSS alternate stylesheet to use when converting the source
        SVG files.
 -cssUser <userStylesheet>
        CSS user stylesheet URI to apply to converted SVG documents
        in addition to any other referened or embeded stylesheets.
 -font-family <defaultFontFamily>
        Value used as a default when no font-family value
        is specified.
 -lang <userLanguage>
        User language to use when converting SVG documents.
 -q <quality>
        Quality for the output image. This is only relevant for the
        image/jpeg mime type.
 -indexed (1|2|4|8)
        Reduces the image to given number of bits per pixel using an
        adaptive pallete, resulting in an Indexed image.  This is
        currently only supported for PNG conversion.
 -dpi <resolution>
        Resolution for the ouptut image.
 -validate
        Controls whether the source SVG files should be validated.
 -onload
        Controls if the source SVG files must be rasterize after
        dispatching the 'onload' event.
 -snapshotTime <time>
        Specifies the document time that should be seeked to before
        rasterizing the document. Specifying this option implies -onload.
 -scriptSecurityOff removes any security check on the scripts running
        as a result of dispatching the onload event.
 -anyScriptOrigin controls whether scripts can be loaded from
         any location. By default, scripts can only be loaded from
        the same location as the document referencing them.
 -scripts <listOfAllowedScripts> List of script types (i.e.,
        values for the type attribute in the <script> tag) which
        should be loaded.

⚠️ 注意:rasterizer 没有 -help/--help 选项——实测 java -jar batik-rasterizer-1.19.jar -help 会把 -help 当成待转换文件而报错:Error: no output directory specified and source is not a file (source causing failure is "file:-help"。看帮助的正确方式就是无参运行。

4.1 输出位置与格式:-d、-m

-d 指定输出目录(单输入文件时也可以是文件名),-m 指定 MIME 类型决定输出格式。不传 -d 时输出写在源文件旁边:

java -jar /opt/batik/batik-rasterizer-1.19.jar /opt/lab/hello.svg

输出节选(实测):

Converting hello.svg to /opt/lab/hello.png ... ... success
java -jar /opt/batik/batik-rasterizer-1.19.jar -m image/jpeg -d /opt/lab/out /opt/lab/hello.svg

输出节选(实测):

Converting hello.svg to /opt/lab/out/hello.jpg ... ... success

两点实测结论:默认格式为 PNG、输出文件名与源同名仅换扩展名;-m image/tiff 时扩展名是 .tif(不是 .tiff,实测产物文件名 hello.tif)。

4.2 尺寸参数:-w、-h、-maxw、-maxh、-dpi、-a

用 PNG 头部(IHDR 块)核对每个参数的实际输出尺寸,od 读取第 16~23 字节即宽高(大端 4 字节整数):

java -jar /opt/batik/batik-rasterizer-1.19.jar -w 800 -h 400 -d /opt/lab/out-wh /opt/lab/hello.svg

输出节选(实测):

Converting hello.svg to /opt/lab/out-wh/hello.png ... ... success
od -An -tu1 -j16 -N8 /opt/lab/out-wh/hello.png

回显(实测):

   0   0   3  32   0   0   1 144

前三字节拼出宽 0x0320=800、后四字节高 0x0190=400,-w/-h 精确生效。其余参数实测结果汇总:

参数实测输入实测输出尺寸结论
-maxw 200400x200 源200x100等比缩到上限,保持纵横比
-a 100,50,200,100 单独400x200 源400x200AOI 区域被缩放铺满画布,尺寸不变
-a 100,50,200,100 -w 200 -h 100400x200 源200x100与 -w/-h 组合才得到原比例裁剪
-dpi 150无单位 px 的 SVG400x200(不变)dpi 只影响带物理单位的文档
-dpi 150width="10cm" height="5cm" 的 SVG591x29510cm 在 150dpi 下为 591px(默认 96dpi 时 378px)

物理单位对照实测(cm 版 SVG 默认渲染):

od -An -tu1 -j16 -N8 /opt/lab/out/cm96/hello-cm.png && od -An -tu1 -j16 -N8 /opt/lab/out/cm150/hello-cm.png

回显(实测):

   0   0   1 122   0   0   0 189
   0   0   2  79   0   0   1  39

默认 96dpi 得 378x189(0x017A、0x00BD),150dpi 得 591x295(0x024F、0x0127),与换算公式一致。

4.3 JPEG 质量:-q 与真实默认值

JPEG 质量梯度实测(同一 400x200 源):

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 的默认输出(5050B)甚至小于 -q 0.8(5486B),因为不带 -q 时 Batik 不设置质量提示、JPEG 编码走 ImageIO 默认参数(内部消息键 jpeg.unspecifiedQuality);显式给 -q 才按给定质量编码。-q 的合法范围用越界值实测——传 -q 1:

java -jar /opt/batik/batik-rasterizer-1.19.jar -m image/jpeg -q 1 -d /opt/lab/out /opt/lab/hello.svg 2>&1 | grep -vE "^WARNING" | 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 本身被拒绝(抛 IllegalArgumentException),实际可用的开区间是 0 < q < 1。

4.4 色深与背景:-indexed、-bg

-indexed 仅对 PNG 有效,把图像降为自适应调色板的索引色:

ls -l /opt/lab/out/hello.png /opt/lab/svg/hello.png | awk '{print $5, $9}'

回显(实测):

3544 /opt/lab/out/hello.png
5870 /opt/lab/svg/hello.png

同为 400x200 源,-indexed 8(256 色)产物 3544B,全彩 PNG 5870B,体积下降约 40%。-bg 255.255.235.205 以「透明像素替换色」形式为 JPEG(无透明通道)指定背景,格式为 a.r.g.b 四段整数。

4.5 CSS 与字体参数:-cssMedia、-cssAlternate、-cssUser、-font-family、-lang

这一组参数控制渲染期的 CSS 环境:-cssMedia 模拟目标媒介(screen/print 等)让 @media 规则按媒介分支;-cssAlternate 选择文档声明的 alternate stylesheet;-cssUser 追加一张用户样式表 URI;-font-family 为未声明 font-family 的文本指定兜底字体;-lang 按用户语言做 systemLanguage 条件渲染。均为 SVGAbstractTranscoder 对应提示键的命令行映射,实测与 -m 组合用法:

java -jar /opt/batik/batik-rasterizer-1.19.jar -cssMedia print -font-family "DejaVu Sans" -lang en -d /opt/lab/out-css /opt/lab/hello.svg

输出节选(实测):

Converting hello.svg to /opt/lab/out-css/hello.png ... ... success

4.6 校验与动画:-validate、-onload、-snapshotTime

-validate 让解析器按 DTD 校验源文件;-onload 决定是否先派发 onload 事件再渲染(涉及脚本执行与安全沙箱,详见第七章);-snapshotTime 把 SMIL 动画定位到指定时刻再截图,并隐含 -onload。

4.7 svgpp 与 ttf2svg 的参数默认值

svgpp(格式化工具)无参运行取官方默认值:

java -jar /opt/batik/batik-svgpp-1.19.jar 2>&1 | grep -E "doc-width|tab-width|newline|default" 

输出节选(实测):

-doc-width <number>
        Sets the document preferred number of columns. The default is 80.
-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).

即 doc-width 默认 80、tab-width 默认 4、换行默认 lf。ttf2svg 的用法为 java org.apache.batik.svggen.font.SVGFont <ttf-path> [-l <range-begin>] [-h <range-end>] [-autorange] [-ascii] [-id <id>] [-o <output-path>] [-testcard](实测无参回显原文),不指定 -l/-h 时默认转换字体全部码位。

五、Transcoder 提示键详解(API 配置)

在 Java 代码里,rasterizer 的多数选项对应 Transcoder 的提示键(hint)。以下键均在本篇实测程序中验证或与命令行实测一一对应:

提示键类实测值与效果
PNGTranscoder.KEY_WIDTH / KEY_HEIGHTPNGTranscoder800f/400f,输出 PNG 实测 800x400(IHDR 0x0320/0x0190)
JPEGTranscoder.KEY_QUALITYJPEGTranscoder0.8f,产物 5486B;缺省时走 ImageIO 默认质量(5050B)
SVGAbstractTranscoder.KEY_AREA_OF_INTERESTSVGAbstractTranscoder对应 rasterizer -a
ImageTranscoder.KEY_BACKGROUND_COLORImageTranscoder对应 rasterizer -bg
SVGAbstractTranscoder.KEY_ALTERNATE_STYLESHEETSVGAbstractTranscoder对应 -cssAlternate
SVGAbstractTranscoder.KEY_USER_STYLESHEET_URISVGAbstractTranscoder对应 -cssUser
SVGAbstractTranscoder.KEY_DEFAULT_FONT_FAMILYSVGAbstractTranscoder对应 -font-family
SVGAbstractTranscoder.KEY_WIDTH / KEY_HEIGHTSVGAbstractTranscoderPNG/JPEG/TIFF 共用的尺寸键

最小验证程序(Maven 工程 /opt/lab/batik-maven,依赖 batik-transcoder 1.19 + batik-codec 1.19):

package com.example;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;

public class SvgToPng {
    public static void main(String[] args) throws Exception {
        TranscoderInput input = new TranscoderInput(
            new File("/opt/lab/batik-maven/hello.svg").toURI().toString());
        PNGTranscoder png = new PNGTranscoder();
        png.addTranscodingHint(PNGTranscoder.KEY_WIDTH, 800f);
        png.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, 400f);
        OutputStream out = new FileOutputStream("/opt/lab/batik-maven/hello-api.png");
        png.transcode(input, new TranscoderOutput(out));
        out.close();
        System.out.println("PNG done -> hello-api.png");
    }
}

编译运行与尺寸复核(实测):

PNG done -> hello-api.png
od -An -tu1 -j16 -N8 /opt/lab/batik-maven/hello-api.png

回显(实测):

   0   0   3  32   0   0   1 144

⚠️ 注意:老资料提到的 XMLAbstractTranscoder.KEY_XML_PARSER_CLASS_NAME 在 1.19 已不存在——实测代码引用该常量编译报 cannot find symbol: variable KEY_XML_PARSER_CLASS_NAME。1.19 的解析器切换走系统属性(见第六章)。

💡 技术拓展:Transcoder 是按输出格式分族的类族,选型对比——

类输出关键专属键
PNGTranscoderPNGKEY_INDEXED(1~8 位索引色)
JPEGTranscoderJPEGKEY_QUALITY(0~1 浮点)
TIFFTranscoderTIFFKEY_COMPRESSION(压缩方式)
PDFTranscoderPDF需另加 FOP pdf-transcoder 依赖

本篇实测采用 PNGTranscoder 与 JPEGTranscoder:PNG 覆盖透明与无损场景,JPEG 覆盖体积敏感场景,均为 batik-codec 内置、无需额外依赖。

六、XML 与 CSS 解析器配置(系统属性)

Batik 的解析器选择集中在 org.apache.batik.util.XMLResourceDescriptor。发行包内资源文件的内容实测如下:

cd /tmp && unzip -p /opt/batik/lib/batik-util-1.19.jar org/apache/batik/util/resources/XMLResourceDescriptor.properties | grep -vE "^#|^$"

回显(实测):

org.w3c.css.sac.driver = org.apache.batik.css.parser.Parser

即 CSS 解析器(SAC)默认用 Batik 自带的 org.apache.batik.css.parser.Parser。XML 侧则读取系统属性 org.xml.sax.driver,实测用 JDK 内置 Xerces 覆盖后转换正常:

cd /opt/lab/batik-maven && java -Dorg.xml.sax.driver=com.sun.org.apache.xerces.internal.parsers.SAXParser -cp target/classes:$(cat cp.txt) com.example.SvgToPng

回显(实测):

PNG done -> hello-api.png
JPEG done -> hello-api.jpg

不设该属性时 Batik 使用 JDK 默认 SAX 实现同样成功,说明此键是「可覆盖项」而非「必填项」。

💡 技术拓展:XML 解析器不止一种选择——

解析器来历特点适用场景
JDK 内置 Xercescom.sun.org.apache.xerces.internal零依赖、随 JVM 走绝大多数部署(本篇实测默认)
独立 Xerces2org.apache.xerces:xercesImpl版本自控、可跟进安全修复需要固定/升级解析器行为
其他 SAX2 实现任意 org.xml.sax.XMLReader只需实现标准接口特殊嵌入环境

本篇按 1.19 默认行为使用 JDK 内置解析器,覆盖方法为 -Dorg.xml.sax.driver=实现类全名。

七、脚本与安全沙箱配置

Batik 在命令行工具启动时就会安装 Java SecurityManager(这是 JDK 17 出现废弃警告的原因),执行 SVG 内脚本(onload 等)时的安全边界由「脚本类型白名单 + 同源限制 + 策略文件」三层组成。以下链路全部实测。

第一步,准备带脚本的 SVG(onload 把背景色改为红色):

cat > /opt/lab/hello-script.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"
     onload="changeColor(evt)">
  <rect id="bg" 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>
  <script type="text/ecmascript"><![CDATA[
    function changeColor(evt) {
      var doc = evt.target.ownerDocument;
      doc.getElementById("bg").setAttribute("fill", "#e53935");
    }
  ]]></script>
</svg>
SVGEOF

回显(实测,写入成功无输出):

第二步,默认(无 -onload)不派发 onload,脚本不执行,输出与静态渲染完全一致(sha256 前 24 位实测 2bd7b2e091762e32015e7808)。

第三步,加 -onload 执行脚本。先记录一个发行包的真实缺陷——lib/ 里其实自带 Rhino(rhino-1.7.7.jar),但 rasterizer 应用 jar 的 MANIFEST Class-Path 只显式列了 16 个 jar、并未引用它,-jar 方式启动会缺类:

java -jar /opt/batik/batik-rasterizer-1.19.jar -onload -d /opt/lab/out2 /opt/lab/hello-script.svg 2>&1 | grep -vE "^WARNING" | head -2

输出节选(实测首部):

Converting hello-script.svg to /opt/lab/out2/hello-script.png ... Exception in thread "main" java.lang.NoClassDefFoundError: org/mozilla/javascript/WrapFactory
        at org.apache.batik.bridge.RhinoInterpreterFactory.createInterpreter(RhinoInterpreterFactory.java:82)
ls /opt/batik/lib/ | grep rhino

回显(实测):

rhino-1.7.7.jar

第四步,改用主类方式、把 lib/ 全部 jar 放进类路径(-jar 模式会忽略 -cp,这是 Java 的固定行为),让自带的 Rhino 1.7.7 被加载:

cd /opt/batik && java -cp "batik-rasterizer-1.19.jar:lib/*" org.apache.batik.apps.rasterizer.Main -onload -d /opt/lab/out2 /opt/lab/hello-script.svg 2>&1 | grep -vE "^WARNING" | tail -3

回显(实测收尾段):

Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "rhino.stack.style" "read")
        at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:1068)

这就是沙箱在工作:Batik 按内置策略资源(jar 内 org/apache/batik/apps/rasterizer/resources/rasterizer.bin.policy)安装 SecurityManager。策略给 lib/ 各 Batik 模块全权限,但对脚本引擎的白名单条目写的是旧文件名 lib/js.jar(限 createClassLoader、Socket、两个特定 PropertyPermission、文件读),而 1.19 实际捆的是 rhino-1.7.7.jar——文件名对不上、授权落空,Rhino 1.7.x 初始化时读系统属性 rhino.stack.style 即被拒。实测该拦截与 Rhino 版本无关:换用 1.7.14、1.7R5、1.7.15 放在类路径首位全部同报错,证明拦截来自策略而非某个 Rhino 版本缺陷。

第五步,-scriptSecurityOff 关闭沙箱再跑(这次暴露的是更深一层的问题——Batik 1.19 的全局包装脚本与 Rhino 全系不兼容):

cd /opt/batik && java -cp "batik-rasterizer-1.19.jar:lib/*" org.apache.batik.apps.rasterizer.Main -onload -scriptSecurityOff -d /opt/lab/out2 /opt/lab/hello-script.svg 2>&1 | grep -vE "^WARNING" | tail -4

回显(实测收尾段):

ERROR: null
Enclosed Exception:
Function importClass must be called with a class; had "[JavaPackage org.w3c.dom.DOMImplementationSource]" instead.
... success

渲染流程走完(success),但 onload 回调实际未生效——产物 sha256 前 24 位仍为 2bd7b2e091762e32015e7808,与第二步静态渲染基线完全一致。把类路径首位分别换成 rhino-1.7.14、1.7R5、1.7R4 复测,全部倒在同一个 importClass 错误上。根因:Batik 初始化脚本解释器时先执行一段全局包装脚本(内含 importClass 等桥接函数),1.19 的这段包装脚本与 Rhino 1.7 全系在 JavaPackage 成员解析行为上不匹配。结论与建议:生产上以「Transcoder API 静态渲染 + 不派发脚本」为主;确需脚本执行时,必须先在目标版本组合下实测验证(1.19 + Rhino 1.7 全系实测均不可用),并关注官方版本公告。

第六步,验证 Transcoder API 的脚本边界:用 Maven 工程(已含 rhino 1.7.15 依赖)对同一文件分别带/不带 Rhino 渲染,产物哈希实测完全一致(均为 2bd7b2e091762e32015e7808)——Transcoder API 是静态渲染,不派发 onload 事件,脚本要执行必须走 rasterizer -onload 或 JSVGCanvas 动态环境。

💡 技术拓展:Batik 支持的脚本引擎不止 ECMAScript 一种——

引擎类型依赖
ECMAScript(Rhino)text/ecmascript、application/javascript发行包 lib/ 自带 rhino-1.7.7.jar(MANIFEST 未引用,且与 1.19 包装脚本不兼容,见本章实测)
Jacl(Tcl)text/tcljacl 包,另行添加
JPythontext/pythonjython 包,另行添加

引擎由 <script type="..."> 的 type 触发、由 batik-script 内的 InterpreterFactory 探测类路径决定;本篇实测以 ECMAScript/Rhino 为主线(最常见)。

策略层面还有两个开关:-scripts <列表> 白名单允许的脚本类型(如 -scripts text/ecmascript),-anyScriptOrigin 允许脚本从任意位置加载(默认仅允许与文档同源)。三者与 -scriptSecurityOff 的取舍:能白名单就不关沙箱,测试调试才用 -scriptSecurityOff。

八、Squiggle 浏览器配置

Squiggle 是 Batik 自带的 Swing SVG 浏览器(batik-squiggle-1.19.jar),无显示环境直接启动会报错(实测):

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.

可运行的前提有两条:JDK 带图形支持(headful 本地库)、存在可用的 X 显示。配置项(窗口布局、缩放、脚本安全选项等)由 Swing 菜单操作,持久化走 JVM 标准的 java.util.prefs 机制(Linux 落在用户主目录 ~/.java/.userPrefs 下,首次保存偏好时生成)。服务器场景一般不用 Squiggle,其安全设置与 rasterizer 同源(同样受 -scriptSecurityOff 对应的选项与策略资源约束)。

九、生产配置模板

按场景给出可直接套用的推荐参数集:

场景一:Web 服务端批量 SVG 转 PNG(4 核 8GB、SSD、日均百万级小图)

java -Xms256m -Xmx512m -jar /opt/batik/batik-rasterizer-1.19.jar \
  -m image/png -w 1024 -h 1024 -indexed 8 -d /data/out /data/svg

要点:堆 256–512MB(单机多进程并行转换时每进程 256MB 更稳);-indexed 8 在可接受色损下显著省存储;输出目录与源分离。

场景二:归档截图、画质优先(16GB 内存、NVMe)

java -Xms256m -Xmx512m -jar /opt/batik/batik-rasterizer-1.19.jar \
  -m image/jpeg -q 0.95 -bg 255.255.255.255 -font-family "DejaVu Sans" -d /data/out /data/svg

要点:JPEG 显式给 -q 0.95(不给出 ImageIO 默认质量);-bg 消除透明区黑块风险;-font-family 统一兜底字体避免各机渲染差异。

场景三:Java 服务内嵌渲染(Spring 等常驻 JVM)

-Xms256m -Xmx512m
PNGTranscoder.KEY_WIDTH/KEY_HEIGHT 显式设定
JPEGTranscoder.KEY_QUALITY 显式设定
不派发脚本(Transcoder 本身静态)

要点:常驻进程用 -Xmx512m 封顶转换峰值;所有提示键显式化,避免依赖 ImageIO 默认值;系统属性 -Dorg.xml.sax.driver 仅在需要固定解析器时设置。

十、常见问题(FAQ)

Q1:找不到 batik.properties,配置文件到底在哪? 不存在。实测全部 jar 检索无 batik.properties 字样(见第三章)。配置走命令行参数、Transcoder 提示键、系统属性与内置策略资源四类入口。

Q2:-help 为什么报错? rasterizer 无帮助选项,无参运行才是选项表;-help 被当成文件名(实测报错见第四章开头)。

Q3:-dpi 150 不生效? dpi 只缩放带物理单位(cm/mm/in/pt)的文档;无单位像素文档不受影响(实测对照见 4.2 节表格)。

Q4:-q 1 报 IllegalArgumentException? 官方文案写 [0,1] 但实测 1 被拒,实际取开区间 0 < q < 1,如 -q 0.99(文案标注默认 0.99)。

Q5:脚本为什么会触发 AccessControlException? Batik 默认沙箱按内置策略限制脚本权限。1.19 实测的直接诱因是内置策略白名单写的 lib/js.jar 与实捆的 rhino-1.7.7.jar 文件名不匹配(授权落空),新版 Rhino 初始化读 rhino.stack.style 属性即被拒(见第七章)。处理路径:改为静态渲染,或白名单脚本类型,调试期才 -scriptSecurityOff——注意 1.19 关沙箱后脚本仍因 importClass 不兼容而不生效。

Q6:Transcoder 代码里找不到 KEY_XML_PARSER_CLASS_NAME? 1.19 已移除该提示键(实测编译 cannot find symbol),用 -Dorg.xml.sax.driver=... 系统属性替代。

十一、参考链接