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


Содержание раздела