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

PDFBox如何获取90/270度旋转文本的(x1,y1)(x2,y2)边界坐标

PDFBox 提取多旋转角度文本边界坐标方案

问题根源

你之前能正确拿到0度、180度文本坐标,是因为这两个角度下文本延伸方向和页面X轴平行,文本宽度对应X轴坐标差、高度对应Y轴坐标差,直接取默认坐标值不会出错。
90度、270度文本的基线和页面X轴垂直,此时文本的视觉宽度对应Y轴坐标差、视觉高度对应X轴坐标差,直接用默认的水平方向坐标取值,只能拿到一条竖线的坐标,自然会出现x1=x2的问题。
你提到的直接互换X/Y取值、硬套宽高做加减的逻辑,只适配纯90度顺时针旋转、无页面偏移、无字体变换的理想场景,遇到270度旋转、页面自带旋转角度、文字有倾斜/位移时,计算结果会完全错位。printWord 方法是为文本排版输出设计的,返回的是适配阅读顺序的调整后坐标,不是页面原始边界坐标,不适合用来做坐标提取。

正确实现方式

不要硬编码角度判断做坐标换算,直接通过TextPosition自带的文本渲染矩阵,计算文本四个角的实际页面坐标,再取极值生成边界框即可,这个方案适配0/90/180/270度所有旋转场景,不需要单独判断文本角度。
实现逻辑:

  • 取文本本地坐标系的四个角点:本地坐标系以文本基线起点为原点,X轴沿文本基线延伸方向,Y轴沿字体高度向上方向
  • 用文本自带的变换矩阵把四个本地坐标点转换为页面实际坐标
  • 对四个转换后的点取X、Y的最小、最大值,得到的就是准确的边界框坐标

示例代码

import org.apache.pdfbox.contentstream.PDFStreamEngine;
import org.apache.pdfbox.text.TextPosition;
import org.apache.pdfbox.util.Matrix;
import java.awt.geom.Point2D;
import java.util.List;

public class RotatedTextCoordExtractor extends PDFStreamEngine {

    @Override
    protected void processTextPosition(TextPosition text) {
        Matrix textMatrix = text.getTextMatrix();
        // 定义文本本地坐标系的四个角点
        Point2D[] localPoints = new Point2D[]{
                new Point2D.Double(0, 0),
                new Point2D.Double(text.getWidth(), 0),
                new Point2D.Double(text.getWidth(), text.getHeight()),
                new Point2D.Double(0, text.getHeight())
        };

        double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
        double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;

        for (Point2D point : localPoints) {
            Point2D pagePoint = textMatrix.transformPoint(point);
            // 如果需要和你之前0/180度的坐标值对齐,保留Y轴翻转逻辑;不需要的话注释下一行即可
            double pageY = getCurrentPage().getMediaBox().getHeight() - pagePoint.getY();
            pagePoint.setLocation(pagePoint.getX(), pageY);

            minX = Math.min(minX, pagePoint.getX());
            minY = Math.min(minY, pagePoint.getY());
            maxX = Math.max(maxX, pagePoint.getX());
            maxY = Math.max(maxY, pagePoint.getY());
        }

        // 最终输出(x1=minX,y1=minY)为边界框左上角,(x2=maxX,y2=maxY)为右下角
        System.out.printf("文本:%s,坐标:(%.0f,%.0f) (%.0f,%.0f),旋转角度:%.0f度%n",
                text.getUnicode(),
                minX, minY, maxX, maxY,
                Math.toDegrees(text.getRotation())
        );
    }
}

注意事项

  • 如果你的业务不需要把PDF原生的左下角原点坐标系转换为常用的左上角原点坐标系,直接删掉Y轴翻转的代码即可,和你之前拿到的0度、180度坐标值可以完全对齐
  • 该方案自动适配页面旋转、文本偏移、字体大小缩放等场景,不需要额外写角度判断逻辑
  • 如果需要提取整词而非单个字符的坐标,可以把同个TextPosition块的字符做聚合,合并相邻字符的边界框即可

内容的提问来源于stack exchange,提问作者tejas Reddy p

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:27:25