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