Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab11_Java_Vkazivky_2010_Mutimedia in Java_ Ima....doc
Скачиваний:
1
Добавлен:
17.04.2019
Размер:
863.23 Кб
Скачать

15.2. Класи-фільтри

Інтерфейс imageConsumer не має рації реалізовувать, використовується його готова реалізація - клас imageFilter. Незважаючи на назву, цей клас не робить ніякої фільтрації, він передає зображення без зміни. Для перетворення зображення даний клас належить розширити, перевизначивши метод setPixeІs(). Результат перетворення належить передати споживачу, роль якого відіграє поле consumer цього класу. В пакеті java. awt. image єсть чотири розширення класу ImageFilter:

  • CropImageFilter (int x, int у, int w, int h) — виділяє фрагмент зображення, указаний в приведеному конструкторі;

  • RGBimageFilter - дозволяеє змінювати окремі пікселі; це абстрактний клас, він вимагає розширення і перевизначення свого методу filterRGB();

  • RepІicateScaІeFilter (int w, int h) — змінює розміри зображення на указані в приведеному конструкторі, дублюючи рядки і/або стовпці при збільшенні розмірів або прибираючи деякі із них при зменшенні;

  • AreaAveragingScaleFilter (int w, int h) — розширення попереднього класу; використовує більш складний алгоритм зміни розмірів зображення, усереднюючий значення сусідніх пікселів.

Застосовуються ці класи разом із іншим класом-постачальником, реалізуючим інтерфейс ImageProducer - класом FilteredlmageSource. Цей класс перетворює уже готову продукцію, отриману від другого постачальника producer, використовуючи для перетворення обєкт filter класу-фільтра imageFilter або його підкласу. Обидва обєкта задаються в конструкторі

FilteredlmageSource(ImageProducer producer, ImageFilter filter)

Все це здається дуже заплутаним, але схема застосування фільтрів завжди одна і та ж. Вона показана в лістингах 15.2—15.4.

15.3. Як виділити фрагмент зображення

В лістинзі 15.2 виділяється фрагмент зображення і виводится на екран у збільшеному вигляді. Крім того, нижче виводяться зображення, збільшені зі допомогною класів RepІicateScaІeFiІter і AreaAveragingScaleFilter.

Лістинг 15.2. Приклади маштабування зображення

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

class CropTest extends Frame{

private Image img, cropimg, replimg, averimg;

CropTest(String s){ super (s) ;

// 1. Створюємо зображення — обєкт класу Image

img = getToolkit().getImage("javalogo52x88.gif");

// 2. Створюємо обєкти-фільтри:

// а) виділяємо лівий верхній кут розміром 30x30

CropImageFilter crp = new CropImageFilter(0, 0, 30, 30);

// б) збільшуємо зображення в два рази простим методом

ReplicateScaleFilter rsf = new ReplicateScaleFilter(104, 176);

// в) збільшуємо зображення в два рази з усредненням

AreaAveragingScaleFilter asf = new AreaAveragingScaleFilter(104, 176);

// 3. Створюємо зміну зображення

cropimg = createImage(new FilteredImageSource(img.getSource(), crp));

replimg = createImage(new FilteredImageSource(img.getSource(), rsf));

averimg = createImage(new FilteredImageSource(img.getSource(), asf));

setSize(400, 350); setVisible(true); }

public void paint(Graphics g){ g.drawImage(img, 10, 40, this);

g.drawImage(cropimg, 150, 40, 100, 100, this);

g.drawImage(replimg, 10, 150, this);

g.drawImage(averimg, 150, 150, this);

}

public static void main(String[] args){

Frame f= new CropTest(" Маштабування");

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent ev){

System.exit(0);

}

});

}

}

На рис. 15.3 зліва зверху показано початкове зображення, справа — збільшений фрагмент, внизу — зображення, збільшене двома способами.

Рис. 15.3. Маштабування зображення

15.4. Як змінити колір зображення

В лістинзі 15.3 змінюються кольори кожного пікселя зображення. Це досягається просто зсувом rgb » 1 вмісту пікселя на один біт вправо в методі fiІterRGB(). При цьому підсилюється червона складова кольору. Метод fiІterRGB() перевизначений в розширенні coІorFilter класу RGBImageFilter.

Лістинг 15.3. Зміна кольору всіх пікселів

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

class RGBTest extends Frame{

private Image img, newimg;

RGBTest(String s){

super(s);

img = getToolkit().getImage("javalogo52x88.gif");

RGBImageFilter rgb = new ColorFilter();

newimg = createImage(new FilteredImageSource(img.getSource(), rgb));

setSize(400, 350);

setVisible(true); }

public void paint(Graphics g){

g.drawImage(img, 10, 40, this);

g.drawImage(newimg, 150, 40, this); }

public static void main(String[] args){

Frame f= new RGBTest(" Зміна кольору");

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent ev){

System.exit(0);

}

});

}

}

class ColorFilter extends RGBImageFilter{ ColorFilter(){

canFilterIndexColorModel = true; }

public int filterRGB(int x, int y, int rgb){

return rgb >> 1;

}

}

15.5. Як переставити пікселі зображення

В лістинзі 15.4 визначається перетворення пікселів зображення. Створюється новий фільтр - розширення shiftFilter класу imageFilter, здвигаючий зображення циклічно вправо на указане в конструкторі число пікселiв. Все, що для цього потрібно, - це перевизначити метод setPixels().

Лістинг 15.4. Циклічний зсув зображення

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

class ShiftImage extends Frame{ private Image img, newimg;

ShiftImage(String s){ super(s);

// 1. Одержуємо зображення із файла

img = getToolkit().getImage("javalogo52x88.gif");

// 2. Створюємо екземпляр фільтра

ImageFilter imf = new ShiftFilter(26);

// Зсув на 26 пікселів

// 3. Одержуємо нові пікселі за допомогою фільтра

ImageProducer ip = new FilteredImageSource(img.getSource(), imf);

// 4. Створюємо нове зображення

newimg = createImage(ip);

setSize(300, 200);

setVisible(true) ; }

public void paint(Graphics gr){

gr.drawImage(img, 20, 40, this);

gr.drawImage(newimg, 100, 40, this); }

public static void main(String[] args){

Frame f= new ShiftImage(" Циклічний зсув зображення");

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent ev){

System.exit(0); }

});

}

}

// Клас-фільтр

class ShiftFilter extends ImageFilter{

private int sh;

// Зсув на sh пікселів вправо.

public ShiftFilter(int shift){ sh = shift; }

public void setPixels(int x, int y, int w, int h,

ColorModel m, byte[] pix, int off, int size){

for (int k = x; k < x+w; k++){

if (k+sh <= w)

consumer.setPixels(k, y, 1, h, m, pix, off+sh+k, size);

else

consumer.setPixels(k, y, 1, h, m, pix, off+sh+k-w, size);

}

}

}

Як видно із листинга 15.4, перевизначення методу setPixels() заключається в тому, щоб змінити аргументи цього методу, переставивши, тим самим, пікселі зображення, і передати їх споживау consumer — полю класу imageFiІter методом setPixels() споживача. На рис. 15.4 показано результат виконання цієї програми. Інша модель обробки зображеня введена в Java 2D. Вона названа моделлю прямого доступу (immediate mode model).

Риc. 15.4. Перестановка пікселів зображення

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]