2014-09-30 4 views
3

Я играю с 2.0.0-SNAPSHOT, и я хочу, чтобы страница была ландшафтной, а также повернула мое изображение. Так что я сделал page.setRotation(90);Apache PDFBox rotate PDImageXObject

Там, кажется, ошибка с использованием PDFBox и AffineTransform

Этот код ничего не делает, как я бы ожидать:

AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20); 
at.translate(0.5, 1); 
at.rotate(Math.toRadians(90)); 

Ширина и высота должны быть маленьким, чтобы сохранить изображение на странице, поворачивать сам по себе, скручивает изображение, а переводить перед поворотом, кажется, масштабирует изображение.

Это ошибка, или я просто не понимаю PDFBox?

+0

Итак, вы создаете матрицу преобразования. Но как вы его используете? И какой эффект вы ожидаете от своих значений трансформации? – mkl

+0

Согласно моему первому предложению: «Я хочу, чтобы страница была ландшафтной, а также поворот изображения». Но и перевод, и вращение имеют смехотворные эффекты масштабирования. – djb

+0

@djb: Я обновил свой ответ. Вчера я не тестировал поворот страницы на 90 °, и, используя его, я получил описанный вами эффект. –

ответ

3

Не делайте дополнительного перевода, вместо этого отправляйте перевод при создании AT. Помните, что вращение вокруг нижней левой оси, поэтому добавьте ширину w в положение x.

PDPage page = new PDPage(); 
    document.addPage(page); 
    page.setRotation(90); 
    PDPageContentStream contentStream = new PDPageContentStream(document, page); 

    int x = 150; 
    int y = 300; 

    // draw unrotated 
    contentStream.drawXObject(ximage, x, y, ximage.getWidth()/2, ximage.getHeight()/2); 

    // draw 90° rotated, placed on the right of the first image 
    AffineTransform at = new AffineTransform(ximage.getHeight()/2, 0, 0, ximage.getWidth()/2, x + ximage1.getWidth(), y); 
    at.rotate(Math.toRadians(90)); 
    contentStream.drawXObject(ximage, at); 

Это изображение будет нарисовано дважды, как обычно, и повернуто на 90 °, и расположено справа. «/ 2» используется для масштабирования 50%, вы можете, конечно, использовать еще один фактор. Обратите внимание, что «/ 2» не используется для начальной позиции x, потому что (масштабированная) ширина требуется дважды. Как только вы переместитесь в прежнее положение (из-за оси!) И один раз, чтобы переместить его вправо, чтобы изображения не перекрывались.

Обратите внимание, что getHeight() и getWidth() меняются на противоположные, для поворота страницы.

+0

Ага, я справился. У тебя это было почти все. Это трюк: AffineTransform at = new AffineTransform (ximage.getWidth()/2, 0, 0, ximage.getHeight()/2, x + ximage1.getWidth(), y); – djb

1
AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20); 
at.translate(0.5, 1); 
at.rotate(Math.toRadians(90)); 

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

Это ошибка, или я просто не понимаю PDFBox?

Это не ошибка, это просто математика. Вам просто нужно знать, что если у вас есть AffineTransform at, а затем позвоните по номеру at.translate(...) или at.rotate(...), вы не сделаете значение перевода/вращения аффинного преобразования в заданные значения, но вместо этого замените ваше преобразование на состав преобразование и перевод/вращение.

Это означает, что, например,

AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20); 
at.translate(0.5, 1); 

является не то же самое, как

AffineTransform at = new AffineTransform(w, 0, 0, h, 20.5, 21); 

, как вы могли бы ожидать, но вместо

AffineTransform at = new AffineTransform(w, 0, 0, h, 20 + w/2, 20 + h); 

Поэтому ширина и высота должны быть крошечным, чтобы сохранить изображение на странице - translate(0.5, 1) нажатие очень далеко в противном случае.

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

AffineTransform at = AffineTransform.getTranslateInstance(0.5, 1); 
at.rotate(Math.toRadians(90)); 
af.concatenate(new AffineTransform(w, 0, 0, h, 20, 20)); 

PS: Как сказал Тильман: Помните, что вращение вокруг дна -left, поэтому эта композиция будет вращаться и за кадром. Просто добавьте h+20 в координату x исходного перевода.

+0

О, я действительно думал, что перевод добавляет значения. Как упоминалось в ответе Тильмана, я решил это сейчас - я использовал его ответ, но мне пришлось менять высоту и ширину. Но вы также очень помогли для информации о матрице, спасибо. – djb

Смежные вопросы