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
相关产品推荐
相关产品推荐

