You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:24:54