Аффинное преобразование изображения
Класс AffineTransform и его использование подробно разобраны в
главе 9,
здесь мы только применим его для преобразования изображения.
В конструкторе класса AffineTransformOp указывается предварительно созданное аффинное преобразование at и способ интерполяции interp и/или правила визуализации hints:
AffineTransformOp(AffineTransform at, int interp); AffineTransformOp(AffineTransform at, RenderingHints hints);
Способ интерполяции — это одна из двух констант:
TYPE_NEAREST_NEIGHBOR
(по умолчанию во втором конструкторе) или
TYPE_BILINEAR
.
После создания объекта класса
AffineTransformOp
применяется метод
filter
(). При этом изображение преобразуется внутри новой области типа
Bufferedimage
, как показано на рис. 15.6, справа. Сама область выделена черным цветом.
Другой способ аффинного преобразования изображения — применить метод drawlmage(Bufferedlmage img, BufferedlmageOp op, int x, int y) класса Graphics2D. При этом преобразуется вся область img, как продемонстрировано на рис. 15.6, посередине.
В листинге 15.5 показано, как задаются преобразования, представленные на рис. 15.6.
Обратите внимание на особенности работы с Bufferedimage. Надо создать графический контекст изображения и вывести в него изображение. Эти действия кажутся лишними, но удобны для двойной буферизации, которая сейчас стала стандартом перерисовки изображений, а в библиотеке Swing выполняется автоматически.
Листинг 15.5.
Аффинное преобразование изображения
import j ava.awt.*;
import Java.awt.geom.*;
import Java.awt. image.*;
import java.awt.event.*;
public class AffOp extends Frame{
private Bufferedimage bi;
public AffOp(String s){ super (s) ;
// Загружаем изображение
img Image img = getToolkit().getlmage("javalogo52x88.gif");
// В этом блоке организовано ожидание загрузки
try{
MediaTracker mt = new MediaTracker(this);
mt.addlmage(img, 0);
mt.waitForlD(O);
// Ждем окончания загрузки }
catch(Exception e){}
// Размеры создаваемой области bi совпадают
//с размерами изображения img
bi = new Bufferedlmage(img.getWidth(this), img.getHeight(this),
Bufferedlmage.TYPE_INT_RGB);
// Создаем графический контекст big изображения bi
Graphics2D big = bi.createGraphics();
// Выводим изображение img в графический контекст
big big.drawImage(img, 0, 0, this);
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
int w = getSize().width;
int h = getSize().height;
int bw = bi.getWidth(this);
int bh = bi.getHeight(this);
// Создаем аффинное преобразование
at AffineTransform at = new AffineTransform();
at.rotate(Math.PI/4); // Задаем поворот на 45 градусов
//по часовой стрелке вокруг левого верхнего угла.
//Затем сдвигаем изображение вправо на величину bw
at.preConcatenate(new AffineTransform(l, 0, О, 1, bw, 0));
// Определяем область хранения bimg преобразованного
// изображения. Ее размер вдвое больше исходного
Bufferedimage bimg =
new Bufferedlmage(2*bw, 2*bw, Bufferedlmage.TYPE_INT_RGB);
// Создаем объект biop,. содержащий преобразование at
BufferedlmageOp biop = new AffineTransformOp(at,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
// Преобразуем изображение, результат заносим в bimg biop.filter(bi, bimg);
// Выводим исходное изображение. g2.drawlmage(bi, null, 10, 30);
// Выводим измененную преобразованием Ыор область bi g2.drawImage(bi, biop, w/4+3, 30);
// Выводим преобразованное внутри области bimg изображение
g2.drawlmage(bimg, null, w/2+3, 30); }
public static void main(String[] args){
Frame f = new AffOpf" Аффинное преобразование");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
f.setSize(400, 200);
f.setVisible(true) ;
}
}
На рис. 15.6 показано исходное изображение, преобразованная область и преобразованное внутри области изображение.
Рис. 15.6. Аффинное преобразование изображения