首页 文章

在PDFBox中,如何更改PDRectangle对象的原点(0,0)?

提问于
浏览
5

情况:
在PDFBox中,PDRectangle对象的默认原点(0,0)似乎是页面的左下角 .

例如,下面的代码在页面的左下角为您提供了一个正方形,每边长度为100个单位 .

PDRectangle rectangle = new PDRectangle(0, 0, 100, 100);

问题:
是否可以将原点更改为UPPER-LEFT转角,例如,上面的代码会在页面的左上角为您提供相同的方块?

我问的原因是:
我使用PDFTextStripper来获取文本的坐标(通过使用提取的TextPosition对象的getX()和getY()方法) . 从TextPosition对象检索的坐标似乎在UPPER-LEFT CORNER处具有原点(0,0) . 我希望我的PDRectangle对象的坐标与我的TextPosition对象的坐标具有相同的原点 .

我试图通过“页面高度减去Y坐标”来调整PDRectangle的Y坐标 . 这给了我想要的结果,但它并不优雅 . 我想要一个优雅的解决方案

注意:有人问过类似的问题 . 答案就是我尝试过的,这不是最优雅的 . how to change the coordiantes of a text in a pdf page from lower left to upper left

3 回答

  • 12

    以下似乎是“调整”TextPosition坐标的最佳方法:

    x_adjusted =  x_original + page.findCropBox().getLowerLeftX();
    y_adjusted = -y_original + page.findCropBox().getUpperRightY();
    

    其中 pageTextPosition 对象所在的 PDPage

  • 4

    你可以稍微改变坐标系,但最有可能的事情不会变得更加优雅 .

    首先......

    首先让我们澄清一些误解:

    你假设

    在PDFBox中,PDRectangle对象的默认原点(0,0)似乎是页面的左下角 .

    对于所有情况都不是这样,仅仅是经常 .

    包含显示的页面区域(在纸上或屏幕上)的区域通常由相关页面的 CropBox 条目定义:

    CropBox矩形(可选;可继承)以默认用户空间单位表示的矩形,用于定义默认用户空间的可见区域 . 当显示或打印页面时,其内容应被剪裁(裁剪)到该矩形,然后以某种实现定义的方式施加在输出介质上 . ...正x轴水平向右延伸,正y轴垂直向上延伸,如标准数学实践(可通过页面字典中的旋转条目进行更改) . ...在PostScript中,默认用户空间的来源始终对应于输出媒体的左下角 . 虽然这种约定在PDF文档中也很常见,但并不是必需的 . 页面字典的CropBox条目可以指定要在介质上显示的任何默认用户空间矩形 .

    因此,它可以位于页面的左下角,左上角,中间或甚至远离显示的页面区域 .

    并通过 Rotate 条目 that area can even be rotated (90°,180°或270°) .

    将原点(如您所观察到的)放在左下方仅按惯例完成 .

    此外,您似乎认为坐标系是不变的 . 实际情况并非如此,您可以通过这些操作大幅度转换用户空间坐标系,您可以平移,旋转,镜像,倾斜和/或缩放它!

    因此,即使在开始时坐标系是通常的坐标系,原点在左下方,x轴向右,y轴向上,也可以在某种程度上改变为页面内容描述中的奇怪的东西 . 绘制矩形 new PDRectangle(0, 0, 100, 100) 可能会在页面中心右侧产生一些菱形形状 .

    你能做什么......

    如您所见,PDF用户空间中的坐标是一个非常动态的问题 . 你可以做些什么来驯服情况,取决于你使用矩形的上下文 .

    不幸的是,你在描述你所做的事情时非常模糊 . 因此,这也有些模糊 .

    页面内容中的坐标

    如果要在现有页面上绘制一些矩形,首先需要一个要写入的页面内容流,即 PDPageContentStream 实例,并且应该以保证原始用户空间坐标系没有受到干扰的方式准备它 . . 通过使用带有三个布尔参数的构造函数将所有它们设置为 true 来获得这样的实例:

    PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true, true);
    

    然后,您可以将变换应用于坐标系 . 您希望左上角是原点,x值向下增加 . 如果页面的裁剪框告诉您左上角有坐标(xtl,ytl),则应用

    contentStream.concatenate2CTM(new AffineTransform(1, 0, 0, -1, xtl, ytl));
    

    从这里你有一个你想要的坐标系,原点左上角和y坐标镜像 .

    但要注意一件事:如果你要绘制文本,不仅文本插入点y坐标是镜像的,而且文本本身除非你通过添加一个镜像文本矩阵来抵消它!因此,如果您想添加更多文本,这可能不如您想要的那么优雅 .

    坐标为注释

    如果您不想在内容流中使用矩形,而是添加注释,则不受上述转换的影响,但您也无法使用它 .

    因此,在此上下文中,您必须按原样拍摄裁剪框并相应地变换矩形 .

    为什么PDFBox文本提取坐标是原样的

    基本上用于以正确的顺序将文本行放在一起并正确排序行,您不需要这种奇怪的情况,而是一个简单的稳定坐标系 . 一些PDFBox开发人员为此选择了左上角,y增加向下的变体,因此 TextPosition 坐标已经标准化为该方案 .

    在我看来,更好的选择是使用默认的用户空间坐标,以便更容易地重复使用坐标 . 因此,您可能希望尝试使用 textPosition.getTextMatrix().getTranslateX()textPosition.getTextMatrix().getTranslateY() 进行 TextPosition textPosition

  • 0

    添加PDF的高度(最简单的解决方案)

相关问题