Преобразование координат PDFbox в iText с использованием AffineTransform

Вопрос:

Кажется, я не могу заставить один формат координат работать с другим форматом. Я думаю, что просто использую не ту матрицу, но я недостаточно знаю о них, чтобы быть уверенным. Я надеялся получить некоторую помощь, чтобы выяснить, делаю ли я предположение о том, каким должно быть мое преобразование.

iText использует левый нижний угол в качестве исходной точки в соответствии со стандартом ISO, но код 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 находится в левом верхнем углу, а 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, и я использую этот пример и tutorial по использованию преобразований.


person Ape-inago    schedule 29.04.2013    source источник
comment
iText использует систему координат, определенную в ISO-32000-1. Если система координат в PDFBox отличается, они используют пользовательское преобразование. Вы правы насчет Матрицы преобразования: принцип работы CTM немного отличается от алгебры, которую нам преподавали в старшей школе. В старших классах мы использовали матрицы для преобразования объекта; в PDF матрица используется для преобразования системы координат. Этот нюанс приводит к разным результатам. Возможно, вам будет проще изменить свои координаты (как учат в старшей школе), чем изменить CTM (как объясняется в ISO-32000-1). Также: пожалуйста, обновите.   -  person Bruno Lowagie    schedule 30.04.2013
comment
Я предполагаю, что это похоже на то, как вы манипулируете объектами в openGL/directX, или что-то вроде примитивов преобразования Processing. Я думаю, что у меня может быть просто неправильное преобразование. Я думал, что переворачивание по оси Y будет таким же, как поворот на 180* и перелистывание по X. Я продолжу экспериментировать. Что вы имеете в виду, когда говорите об обновлении?   -  person Ape-inago    schedule 30.04.2013
comment
Что касается обновления, я вижу, что вы используете мое имя в своем коде. Пожалуйста, прочитайте lowagie.com/itext2   -  person Bruno Lowagie    schedule 30.04.2013
comment
Аргумент, который использует ваш адвокат, кажется мне тактикой запугивания... Все, что МОЖЕТ, имеет содержание, нарушающее авторские права. Мы можем нести такую ​​же ответственность за последнюю версию под agpl (или платной лицензией), как и за предыдущую, или за использование чего-либо под лицензией LGPL, например, hibernate. Аргумент в основном говорит о том, что мы не должны использовать какой-либо сторонний код независимо от лицензии.   -  person Ape-inago    schedule 30.04.2013
comment
Какие гарантии того, что в вашей кодовой базе по-прежнему нет плохого кода? Я не читал никаких журналов изменений, касающихся очистки исходного кода, и тот пост, который вы написали, похоже, был написан через 2 года 8 месяцев после выпуска 5.0. Эта статья - единственная ссылка на эту проблему, которую я могу найти. Заказывали ли вы аудит исходного кода через третью сторону, на которую мы можем сослаться? Они нашли плохие вещи?   -  person Ape-inago    schedule 30.04.2013
comment
Я думаю, что мы застряли с использованием той версии, которую Jasper iReports использует для внутренних целей, из соображений совместимости. если это действительно большая проблема, нам, возможно, придется обратиться к другому поставщику услуг и связаться с их юридической командой. Как лучше всего связаться с кем-то, кто стоит за itext?   -  person Ape-inago    schedule 30.04.2013
comment
Обзор ИС см. в этой старой презентации: slideshare.net/blowagie/itext-ip- обзор Чтобы связаться с кем-нибудь из iText: itextpdf.com/sales   -  person Bruno Lowagie    schedule 01.05.2013
comment
Увлекательно, спасибо за презентацию. Этот последний слайд относится к 2007 году. Были ли еще какие-то изменения между этой датой и выпуском 2009 года, которые не касались бы возможной ответственности? Мне кажется странным, что несмотря на это, Jasper все еще работает на версии 2.1.7.   -  person Ape-inago    schedule 01.05.2013
comment
В 2011 г. была проведена вторая проверка ИС. С момента первоначальной проверки ИС у нас есть дисциплина документировать все новые вклады. Участники, не входящие в группу iText, подписывают лицензионное соглашение с участниками.   -  person Bruno Lowagie    schedule 01.05.2013


Ответы (1)


Я понял. Когда я подбирал координату 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();
person Ape-inago    schedule 01.05.2013
comment
Да, перевод отсутствовал в вашем первоначальном преобразовании. - person Bruno Lowagie; 01.05.2013
comment
А теперь текст пишет вверх ногами... Ура, больше трансформаций. Спасибо, что нашли время, чтобы рассмотреть вещи. Я подал заявку на заказ второго издания вашей книги - кажется, что есть много улучшений, и их стоит обновить, даже если нам придется заплатить некоторые сборы. - person Ape-inago; 03.05.2013
comment
Я начал писать третье издание. Я сделаю это бесплатным, но... Я только начал писать в прошлый вторник, и у меня всего 17 страниц. Что касается последних релизов: да, функционала добавилось много. - person Bruno Lowagie; 03.05.2013
comment
По поводу А теперь текст пишет вверх ногами... Если вы не хотите, чтобы это произошло, вы можете просто использовать трансформацию перевода, а не ту, что переворачивается по y=0. Это дает вам систему координат с началом влево, но с отрицательными координатами y в области страницы. Чтобы использовать координаты из этих других программ, вам просто нужно изменить знак координаты y. Без переворачивающего преобразования текст больше не будет отображаться вверх ногами... - person mkl; 06.05.2013