Иллюстрированный самоучитель по Java
Аффинное
преобразование изображения
Класс 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. Аффинное
преобразование изображения