Абстрактный класс Convolver выполняет базовую обработку фильтра свертывания, реализуя интерфейс потребителя imageConsumer для перемещения исходных пикселов в массив с именем imgpixels. Он также создает второй массив с именем newimgpixels для фильтрованных данных. Фильтры свертывания производят выборку маленького прямоугольника пикселов вокруг каждого пиксела в изображении, называемого ядром свертывания. Эта область (3x3 пиксела в данной демонстрации) используется для принятия рещения, как следует изменить центральный пиксел в этой области. Два конкретных подкласса, показанные в следующем разделе, просто реализуют метод convolve(), используя imgpixels для исходных данных и newimgpixels для сохранения результата.
Причина того, что фильтр не может изменять массив imgpixels на месте, заключается в том, что следующий пиксел на строке сканирования пробовал бы использовать первоначальное значение для предыдущего пиксела, который был только что отфильтрован.
// Файл Convolver.java
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
abstract class Convolver implements ImageConsumer, PlugInFilter {
int width, height;
int imgpixels[], newimgpixels[];
abstract void convolve(); // Здесь идет фильтр
public Image filter(Applet a, Image in) {
in.getSource().startProduction(this);
waitForImage();
newimgpixels = new int[width * height];
try {
convolve();
}
catch (Exception e) {
System.out.println("Convolver failed: " + e);
e.printStackTrace();
}
return a.createImage(
new MemoryImageSource(width, height, newimgpixels, 0, width));
}
synchronized void waitForImage() {
try {
wait();
}
catch (Exception e) { }
}
public void setProperties(java.util.Hashtable dummy) { }
public void setColorModel(ColorModel dummy) { }
public void setHints(int dummy) { }
public synchronized void imageComplete(int dummy) {
notifyAll();
}
public void setDimensions(int x, int y) {
width = x;
height = y;
imgpixels = new int[x * y];
}
public void setPixels(int x1, int y1, int w, int h,
ColorModel model, byte pixels[], int off, int scansize) {
int pix, x, y, x2, y2, sx, sy;
x2 = x1 + w;
y2 = y1 + h;
sy = off;
for(y = y1; y < y2; y++) {
sx = sy;
for(x = x1; x < x2; x++) {
pix = model.getRGB(pixels[sx++]);
if((pix & 0xff000000) == 0)
pix = 0x00ffffff;
imgpixels[y * width + x] = pix;
}
sy += scansize;
}
}
public void setPixels(int x1, int y1, int w, int h,
ColorModel model, int pixels[], int off, int scansize) {