Аффинное преобразование изображения
Класс 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. Аффинное преобразование изображения