Применение нескольких аффинных преобразований в батике

Я пытаюсь масштабировать и перевести изображение SVG в Batik. Для масштабирования я использую

AffineTransform at= new AffineTransform();
at.scale(sx, sy);
at.translate(tx, ty);
canvas.setRenderingTransform(at, true);

Это прекрасно работает (после того, как я узнал, что значения sx, sy, tx и ty должны быть экранными координатами, а не координатами SVG).

Но я хочу разрешить несколько операций масштабирования. Проблема в следующем: у меня не получается "добавить" еще одно преобразование к существующему.

Я попробовал это, сначала вернув старое преобразование, а затем применив новое. Но это подводит меня к другой проблеме: реверсия не работает! Это приводит к тому, что изображение меньше исходного (таким образом, уменьшается масштаб).

Я немного поэкспериментировал и попытался применить преобразование, затем применить обратное, а затем снова применить исходное:

final AffineTransform at= new AffineTransform();
at.scale(zoom.sx, zoom.sy);
at.translate(zoom.tx, zoom.ty);
canvas.setRenderingTransform(at, true);
...
final AffineTransform reverseAt = at.createInverse();
canvas.setRenderingTransform(reverseAt, true);
...
final AffineTransform reverseBackAt= reverseAt.createInverse();
canvas.setRenderingTransform(reverseBackAt, true);

Первое преобразование правильное. Второй приводит к мусору, но повторное применение исходного (или обратного к обратному) приводит к правильному результату.

Собственно, вопросов два:

  • Каков наилучший способ применить несколько операций масштабирования?
  • Почему результат обратного преобразования не такой, как я ожидал?

person radlan    schedule 13.02.2014    source источник


Ответы (1)


Чтобы ответить на первый вопрос, используйте AffineTransform.concatenate():

AffineTransform firstTransform = new AffineTransform();
at.scale(sx, sy);
at.translate(tx, ty);

// Example: double all sizes
AffineTransform secondTransform = AffineTransform.getScaleInstance(2, 2)

secondTransform.concatenate(firstTransform);
canvas.setRenderingTransform(secondTransform, true);
person ComFreek    schedule 11.06.2014