java - 使用 PDFBox 和 Apache Batik 的 PDF 到 SVG 渲染问题
问题描述
我正在使用 PDFBox 与 Apache Batik 的组合,以便将 PDF 页面呈现为 SVG 文档。它们中的大多数都可以正常工作,但是在将特定图像渲染为 SVG 时我遇到了一些问题。
这是我使用的代码。主要是根据那边的帖子。
public void extractBookSvg(File pdfFile) throws Exception {
// ... preliminary business actions
SVGGeneratorContext ctx = createContext();
SVGGraphics2D g = null;
try (PDDocument document = PDDocument.load(pdfFile, MemoryUsageSetting.setupMixed(2147483648l))) {
PDFRenderer renderer = new PDFRenderer(document);
long startTime = System.currentTimeMillis();
int pageNr = 0;
for (PDPage page : document.getPages()) {
long startTimeForPage = System.currentTimeMillis();
g = createGraphics(ctx);
renderer.renderPageToGraphics(pageNr, g, 3.47222f);
pageNr++;
try (OutputStream os = new ByteArrayOutputStream();
Writer out = new OutputStreamWriter(os)) {
g.stream(out, true);
//... do other business actions
}
}
}
finally {
pdfFile.delete();
if (g != null) {
g.finalize();
g.dispose();
}
}
}
private SVGGraphics2D createGraphics(SVGGeneratorContext ctx) {
SVGGraphics2D g2d = new CustomSVGGraphics2D(ctx, false);
return g2d;
}
private SVGGeneratorContext createContext() {
DOMImplementation impl = GenericDOMImplementation.getDOMImplementation();
String svgNS = "http://www.w3.org/2000/svg";
Document myFactory = impl.createDocument(svgNS, "svg", null);
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
return ctx;
}
public static class CustomSVGGraphics2D extends SVGGraphics2D {
public CustomSVGGraphics2D(SVGGeneratorContext generatorCtx, boolean textAsShapes) {
super(generatorCtx, textAsShapes);
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return new CustomGraphicsConfiguration();
}
}
private static final class CustomGraphicsConfiguration extends GraphicsConfiguration {
@Override
public AffineTransform getNormalizingTransform() {
return null;
}
@Override
public GraphicsDevice getDevice() {
return new CustomGraphicsDevice();
}
@Override
public AffineTransform getDefaultTransform() {
return null;
}
@Override
public ColorModel getColorModel(int transparency) {
return null;
}
@Override
public ColorModel getColorModel() {
return null;
}
@Override
public java.awt.Rectangle getBounds() {
return null;
}
}
private static final class CustomGraphicsDevice extends GraphicsDevice {
@Override
public int getType() {
return 0;
}
@Override
public String getIDstring() {
return null;
}
@Override
public GraphicsConfiguration[] getConfigurations() {
return null;
}
@Override
public GraphicsConfiguration getDefaultConfiguration() {
return null;
}
}
如上所述,渲染图像时会出现问题:它们要么根本不渲染(显示为黑框),要么在不透明度低于 1 的某些图像上显示为不透明度 1。
以下是这两种情况的示例:
但是,如果我直接将这些页面渲染为图像(使用 BufferedImage 而不是 Graphics2D),它们都可以很好地渲染(当然,质量低于 svg)。
此外,我尝试使用 PDFDebugger 实用程序调试 PDF,这些图像没有出现在页面的资源 XObject 列表中,而且我似乎无法在其他地方找到它们。
我的问题是:
- 如何确定问题是来自 PDFBox 呈现到 Graphics2D 对象的方式,还是来自 Batik 生成 SVG 的方式?
- 有没有办法确保这些图像在生成时正确显示?因为我在日志中看不到任何错误。
- 如果是这样,解决方案可能是什么?
谢谢!
解决方案
推荐阅读
- javascript - 使用 Owl-Carousel 进行评论的响应式滑块
- azure - Power Apps:让用户从 Azure AD 到 Power Apps 视图以列出表格并刷新表格按钮
- sql - 如何识别 Teradata 中 SQL 的偏斜度
- amazon-web-services - 如何重置或从头开始 aws cdk 配置?
- c++ - 如何在同一帧中替换背景图片和wxBoxSizer?
- arrays - Python itertools.combinations:如何同时获取组合内组合数的索引
- spring-boot - 带有 Springboot 的 Swagger 3:无法推断基本 url
- python - 你如何调试pydoit?
- azure - 微软图形。异常 SubscriptionCountReached 已达到“1000”的限制
- javascript - 在构建应用程序时,Expo/React-Native 将什么捆绑在一起?