首页 文章

PDFbox到iText使用AffineTransform协调转换

提问于
浏览
0

问题:

我似乎无法使用一种坐标格式来处理其他格式 . 我想我只是没有使用正确的矩阵,但我不太清楚他们是否确定 . 我希望得到一些帮助,弄清楚我是否正在考虑我的改造应该是什么 .

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 回答

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

相关问题