PDFbox到iText使用AffineTransform协调转换

时间:2013-04-29 19:45:02

标签: java awt itext pdfbox affinetransform

问题:

我似乎无法使用一种坐标格式来处理其他格式。我想我只是没有使用正确的矩阵,但我不确定它们是否足以确定。我希望得到一些帮助,弄清楚我是否应该对我的转换做出假设。

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

我应该采取什么样的转换来调整坐标,以便iText能够以一种有效的方式消耗它们?

背景

我有一些代码使用pdfbox来操作pdf并删除一些数据,现在我需要将修改后的数据注入页面。 PDFBox的作者一直在破坏pdf,因此我们决定使用iText进行注射。

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

到目前为止我做了什么

我查了一下,iText页面和cropbox似乎都很准确:

  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的原点在左上角,而iTexts在左下角。

我遇到麻烦的地方

当我应用变换时:

  //  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?

concatCTM函数的格式与awt.geom.affinetransform的格式相同,我使用this exampletutorial进行转换。

1 个答案:

答案 0 :(得分:2)

我明白了。当我在削减y坐标时,我假设它将翻转文档的中间并且只是反转所有内容。然而它实际上翻转了y = 0;

翻转y = 0后,您需要重新调整整个页面。

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

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();