如何使用PDFBox检测PDF中的内容缩放比例?
PDFBox获取页面缩放比例问题
我有一份包含扫描文档图片的PDF,页面的第一个内容流如下:
0.36 0 0 0.36 0 0 cm q 2200 0 0 1700 0 0 cm /Im1 Do Q
该页面被缩放到原尺寸的36%,且未执行save/restore操作,会影响页面后续的内容流。
我需要使用PDFBox通过新内容流向页面添加文本,为修正缩放问题,我计算了缩放的逆变换并添加到文本之前,第二个内容流如下:
q 2.77778 0 0 2.77778 0 0 cm BT 0 Tr /F1 37.75083 Tf 67 531 Td /DeviceRGB cs 1 0 0 sc 1 0 0 1 67 531 Tm (\000U\000R\000J\000H\000U\000V\000R\000Q) Tj ET Q
这种硬编码逆变换的方法可行,但我需要基于页面当前状态程序化计算缩放比例,而非使用固定值。
尝试的解决方案及遇到的问题
直接获取页面矩阵
我尝试用PDFBox直接获取当前缩放比例,但结果始终为1.0:
@SneakyThrows @Test void debug() { var source = new ClassPathResource("pdf/scaling/test.pdf").getFile(); @Cleanup var pdf = PDDocument.load(source); var page = pdf.getPage(0); assertEquals(0.36, page.getMatrix().getScaleX()); assertEquals(0.36, page.getMatrix().getScaleY()); }
运行后报错:
AssertionFailedError: Expected :0.36 Actual :1.0
使用PDFStreamEngine处理页面
我推测需要渲染页面才能确定实际缩放比例,但使用PDFStreamEngine处理页面后,缩放比例仍为1:
@SneakyThrows @Test void scalingDetection() { var source = new ClassPathResource("pdf/scaling/test.pdf").getFile(); @Cleanup var pdf = PDDocument.load(source); DebugStreamEngine engine = new DebugStreamEngine(); engine.processPage(pdf.getPage(0)); assertEquals(0.36f, engine.getScalingX()); assertEquals(0.36f, engine.getScalingY()); } protected class DebugStreamEngine extends PDFStreamEngine { public DebugStreamEngine() { addOperator(new Concatenate()); addOperator(new DrawObjectOperator()); addOperator(new BeginInlineImageOperator()); addOperator(new SetGraphicsStateParameters()); addOperator(new Save()); addOperator(new Restore()); addOperator(new SetMatrix()); } @Override protected void processOperator(Operator operator, List<COSBase> operands) throws IOException { log.info("Processing operator: {}", operator.getName()); } protected float getScalingX() { return getGraphicsState().getCurrentTransformationMatrix().getScaleX(); } protected float getScalingY() { return getGraphicsState().getCurrentTransformationMatrix().getScaleY(); } }
运行后报错:
AssertionFailedError: Expected :0.36 Actual :1.0
疑问
我猜测这可能是PDFStreamEngine.processStream重置了图形栈导致的,目前通过自行维护图形栈解决了问题,但想知道是否有更优的方案,或者这是否是PDFBox的bug?
内容的提问来源于stack exchange,提问作者Mike Cantrell
相关产品推荐
相关产品推荐

