我将PDFBox与Apache Batik结合使用,以便将PDF页面呈现为SVG文档。它们中的大多数都能正常工作,但是在将特定图像渲染为SVG时遇到一些问题。
这是我使用的代码。它主要基于there上的帖子。
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。>
以下是这两种情况的示例:
PDF render of transparent image
SVG render of transparent image
These images do not get rendered at all in SVG
How they actually show in the SVG
但是,如果我直接将这些页面呈现为图像(使用BufferedImage而不是Graphics2D),它们都可以很好地呈现(当然,质量要比svg低)。
此外,我尝试使用PDFDebugger实用工具调试PDF,这些图像没有出现在页面的资源XObject列表中,并且似乎在其他任何地方都找不到。
我的问题是:
谢谢!