PDFbox到iText坐标转换使用仿射变换



问题:

我似乎无法将一种坐标格式与另一种格式配合使用。我想我只是没有使用正确的矩阵,但我对它们的了解还不够确定。我希望能得到一些帮助,弄清楚我是否在假设我的转变应该是什么

根据ISO标准,iText使用左下角作为原点,但pdfbox代码和为我提供从pdf中抓取坐标的程序都使用左上角作为原点。

我应该做什么变换来调整坐标,以便iText能够以有效的方式使用它们?

背景

我有一些代码使用pdfbox来操作pdf并剥离一些数据,现在我需要将修改后的数据重新注入页面。PDFBox的作者一直在破坏pdf,所以我们决定使用iText来进行注入。

诀窍是,我在pdfbox中使用的坐标(以及我们从生成pdf的系统中获得的坐标(似乎与iText不匹配。

到目前为止我做了什么

我检查了一下,iText页面和隔板似乎都是准确的:

  PdfReader splitPDFDocumentReader = new PdfReader(splitPDFdocumentName);
  com.lowagie.text.Rectangle theCropBox = splitPDFDocumentReader.getCropBox(1);
  com.lowagie.text.Rectangle thePageSize = splitPDFDocumentReader.getPageSize(1);
  consolePrintln("Cropbox: " + theCropBox.toString());
  consolePrintln("tBottom " + theCropBox.getBottom());
  consolePrintln("tLeft " + theCropBox.getLeft());
  consolePrintln("tTop " + theCropBox.getTop());
  consolePrintln("tRight " + theCropBox.getRight());
  consolePrintln("PageSize: " + thePageSize.toString());
  consolePrintln("tBottom " + thePageSize.getBottom());
  consolePrintln("tLeft " + thePageSize.getLeft());
  consolePrintln("tTop " + thePageSize.getTop());
  consolePrintln("tRight " + thePageSize.getRight());

输出:

Cropbox: Rectangle: 612.0x792.0 (rot: 0 degrees)
    Bottom 0.0
    Left 0.0
    Top 792.0
    Right 612.0
PageSize: Rectangle: 612.0x792.0 (rot: 0 degrees)
    Bottom 0.0
    Left 0.0
    Top 792.0
    Right 612.0

这让我相信这只是翻转y坐标的问题,因为pdfbox的原点在左上角,而iText在左下角。

我遇到麻烦的地方

当我应用转换时:

  //  matrix data example:
  //  [m00, m01, m02,
  //   m10, m11, m12,
  //   0  , 0  , 1   ]  // this bit is implied as part of affineTransform docs
  content.saveState();
  int m00 = 1;
  int m01 = 0;
  int m02 = 0;
  int m10 = 0;
  int m11 = -1;
  int m12 = 0;
  content.concatCTM(m00, m10, m01, m11, m02, m12);
  content.setColorStroke(Color.RED);
  content.setColorFill(Color.white);
  content.rectangle(x, y, x + height, y + width);
  content.fillStroke();
  content.restoreState();

它似乎没有达到我的预期。数据似乎完全在页面之外。

杂项注释

老实说,我对矩阵不是很在行,也许我需要做一些翻译工作,而不是像我试图做的那样只偷y?

concatTM函数似乎采用了与awt.geom.affinetransform相同的格式,我将通过这个例子和教程来使用转换。

我想明白了。当我在绘制y坐标时,我假设它会翻转到文档的中间,并将所有内容翻转过来。然而,它实际上在y=0这条线上翻转;

在它翻转到y=0之后,您需要将整个页面移回原来的位置。

我最终直接使用affineTransform来完成它,然后将生成的矩阵输入concatTM。

content.saveState();
AffineTransform transform = new AffineTransform();
transform.scale(1, -1); // flip along the line y=0
transform.translate(0, -pageHeight); // move the page conet back up
/* the version of iText used in Jasper iReport doesn't seem to use affineTransform directly */
double[] transformMatrix = new double[6];
transform.getMatrix(transformMatrix);
content.concatCTM((float) transformMatrix[0], (float) transformMatrix[1], (float) transformMatrix[2], (float) transformMatrix[3], (float) transformMatrix[4], (float) transformMatrix[5]);
// drawing and printing code here (stamping?)
content.restoreState();

最新更新