83、Java 图像编程:从基础到高级过滤

Java 图像编程:从基础到高级过滤

1. 图像加载与跟踪

在 Java 中处理图像时,首先要考虑的是如何加载和跟踪图像。可以在 init() 方法中创建一个新的 MediaTracker ,并使用 addImage() 方法将每个命名图像添加为跟踪图像。在 paint() 方法中,对正在跟踪的每个图像调用 checkID() 方法。如果所有图像都已加载,则显示它们;否则,显示一个简单的条形图,展示已加载图像的数量,并在条形图下方显示已完全加载的图像名称。

以下是一个简单示例:

// 示例代码:图像加载与跟踪
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class ImageLoader extends Applet {
    MediaTracker tracker;
    Image img;

    public void init() {
        tracker = new MediaTracker(this);
        img = getImage(getDocumentBase(), "example.jpg");
        tracker.addImage(img, 0);
    }

    public void paint(Graphics g) {
        if (tracker.checkID(0)) {
            g.drawImage(img, 0, 0, this);
        } else {
            // 显示加载进度
            g.drawString("Loading...", 10, 30);
        }
    }
}

操作步骤:

  1. 创建 MediaTracker 对象。
  2. 使用 getImage() 方法获取图像。
  3. 使用 addImage() 方法将图像添加到 MediaTracker 中。
  4. paint() 方法中,使用 checkID() 方法检查图像是否加载完成。

2. ImageProducer 接口

ImageProducer 是一个接口,用于为图像生成数据的对象。实现 ImageProducer 接口的对象将提供表示图像数据的整数或字节数组,并生成 Image 对象。 java.awt.image 包中包含两个图像生成器: MemoryImageSource FilteredImageSource

2.1 MemoryImageSource 类

MemoryImageSource 类从数据数组创建新的 Image 对象。它定义了几个构造函数,常用的构造函数如下:

MemoryImageSource(int width, int height, int pixel[], int offset, int scanLineWidth)

该构造函数使用 pixel 数组中的整数,在默认 RGB 颜色模型下为 Image 对象生成数据。在默认颜色模型中,像素是一个包含 Alpha、Red、Green 和 Blue(0xAARRGGBB)的整数。Alpha 值表示像素的透明度,完全透明为 0,完全不透明为 255。

以下是一个使用 MemoryImageSource 生成图像的示例:

/*
 * <applet code="MemoryImageGenerator" width=256 height=256>
 * </applet>
 */
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class MemoryImageGenerator extends Applet {
    Image img;

    public void init() {
        Dimension d = getSize();
        int w = d.width;
        int h = d.height;
        int pixels[] = new int[w * h];
        int i = 0;

        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                int r = (x ^ y) & 0xff;
                int g = (x * 2 ^ y * 2) & 0xff;
                int b = (x * 4 ^ y * 4) & 0xff;
                pixels[i++] = (255 << 24) | (r << 16) | (g << 8) | b;
            }
        }
        img = createImage(new MemoryImageSource(w, h, pixels, 0, w));
    }

    public void paint(Graphics g) {
        g.drawImage(img, 0, 0, this);
    }
}

操作步骤:

  1. 创建一个整数数组 pixels 来存储像素值。
  2. 使用嵌套的 for 循环生成像素数据。
  3. 创建 MemoryImageSource 对象,传入图像的宽度、高度、像素数组、偏移量和扫描线宽度。
  4. 使用 createImage() 方法创建 Image 对象。
  5. paint() 方法中绘制图像。

2.2 流程图:MemoryImageSource 图像生成流程

graph TD;
    A[初始化 Applet] --> B[获取 Applet 大小];
    B --> C[创建像素数组];
    C --> D[生成像素数据];
    D --> E[创建 MemoryImageSource 对象];
    E --> F[创建 Image 对象];
    F --> G[绘制图像];

3. ImageConsumer 接口

ImageConsumer 是一个接口,用于从图像中获取像素数据并将其作为另一种数据提供的对象。它与 ImageProducer 相反。实现 ImageConsumer 接口的对象将从 Image 对象创建表示像素的整数或字节数组。这里将介绍 PixelGrabber 类,它是 ImageConsumer 接口的一个简单实现。

3.1 PixelGrabber 类

PixelGrabber 类定义在 java.lang.image 包中,它是 MemoryImageSource 类的逆操作。它不是从像素值数组构造图像,而是从现有图像中获取像素数组。

PixelGrabber 的构造函数如下:

PixelGrabber(Image imgObj, int left, int top, int width, int height, int pixel[], int offset, int scanLineWidth)

操作步骤:

  1. 创建一个足够大的整数数组来存储像素数据。
  2. 创建 PixelGrabber 实例,传入要抓取的矩形区域。
  3. 调用 grabPixels() 方法获取像素数据。

以下是一个抓取图像像素并创建像素亮度直方图的示例:

/*
 * <applet code=HistoGrab width=400 height=345>
 * <param name=img value=Lilies.jpg>
 * </applet> 
 */
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class HistoGrab extends Applet {
    Dimension d;
    Image img;
    int iw, ih;
    int pixels[];
    int w, h;
    int hist[] = new int[256];
    int max_hist = 0;

    public void init() {
        d = getSize();
        w = d.width;
        h = d.height;

        try {
            img = getImage(getDocumentBase(), getParameter("img"));
            MediaTracker t = new MediaTracker(this);

            t.addImage(img, 0);
            t.waitForID(0);
            iw = img.getWidth(null);
            ih = img.getHeight(null);
            pixels = new int[iw * ih];
            PixelGrabber pg = new PixelGrabber(img, 0, 0, iw, ih, pixels, 0, iw);
            pg.grabPixels();
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
            return;
        }

        for (int i = 0; i < iw * ih; i++) {
            int p = pixels[i];
            int r = 0xff & (p >> 16);
            int g = 0xff & (p >> 8);
            int b = 0xff & (p);
            int y = (int) (.33 * r + .56 * g + .11 * b);
            hist[y]++;
        }
        for (int i = 0; i < 256; i++) {
            if (hist[i] > max_hist)
                max_hist = hist[i];
        }
    }

    public void update() {}

    public void paint(Graphics g) {
        g.drawImage(img, 0, 0, null);
        int x = (w - 256) / 2;
        int lasty = h - h * hist[0] / max_hist;

        for (int i = 0; i < 256; i++, x++) {
            int y = h - h * hist[i] / max_hist;
            g.setColor(new Color(i, i, i));
            g.fillRect(x, y, 1, h);
            g.setColor(Color.red);
            g.drawLine(x - 1, lasty, x, y);
            lasty = y;
        }
    }
}

3.2 表格:PixelGrabber 方法说明

方法 描述
boolean grabPixels() 尝试抓取像素数据,成功返回 true ,失败返回 false ,可能抛出 InterruptedException 异常。
boolean grabPixels(long milliseconds) 在指定的毫秒数内尝试抓取像素数据,成功返回 true ,失败返回 false ,可能抛出 InterruptedException 异常。

4. ImageFilter 类

基于 ImageProducer ImageConsumer 接口及其具体类 MemoryImageSource PixelGrabber ,可以创建任意一组转换过滤器,对像素源进行修改并传递给任意消费者。 ImageFilter 类完善了图像的流模型。 java.awt.image 包中的一些 ImageFilter 子类包括 AreaAveragingScaleFilter CropImageFilter ReplicateScaleFilter RGBImageFilter 。还有一个名为 FilteredImageSource ImageProducer 实现,它将任意 ImageFilter 包装在 ImageProducer 周围,对其生成的像素进行过滤。

4.1 CropImageFilter 类

CropImageFilter 用于过滤图像源,提取矩形区域。当需要从单个较大的源图像中使用多个小图像时,这个过滤器非常有用。

以下是一个从单个图像中创建 16 个图像并打乱它们的示例:

/*
 * <applet code=TileImage width=400 height=345>
 * <param name=img value=Lilies.jpg>
 * </applet>
 */
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class TileImage extends Applet {
    Image img;
    Image cell[] = new Image[4 * 4];
    int iw, ih;
    int tw, th;

    public void init() {
        try {
            img = getImage(getDocumentBase(), getParameter("img"));
            MediaTracker t = new MediaTracker(this);
            t.addImage(img, 0);
            t.waitForID(0);
            iw = img.getWidth(null);
            ih = img.getHeight(null);
            tw = iw / 4;
            th = ih / 4;
            CropImageFilter f;
            FilteredImageSource fis;
            t = new MediaTracker(this);
            for (int y = 0; y < 4; y++) {
                for (int x = 0; x < 4; x++) {
                    f = new CropImageFilter(tw * x, th * y, tw, th);
                    fis = new FilteredImageSource(img.getSource(), f);
                    int i = y * 4 + x;
                    cell[i] = createImage(fis);
                    t.addImage(cell[i], i);
                }
            }
            t.waitForAll();
            for (int i = 0; i < 32; i++) {
                int si = (int) (Math.random() * 16);
                int di = (int) (Math.random() * 16);
                Image tmp = cell[si];
                cell[si] = cell[di];
                cell[di] = tmp;
            }
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
    }

    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics g) {
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                g.drawImage(cell[y * 4 + x], x * tw, y * th, null);
            }
        }
    }
}

操作步骤:

  1. 获取源图像。
  2. 使用 CropImageFilter 提取矩形区域。
  3. 使用 FilteredImageSource 包装过滤器和图像源。
  4. 创建新的 Image 对象。
  5. 打乱图像顺序。

4.2 RGBImageFilter 类

RGBImageFilter 用于逐像素地将一个图像转换为另一个图像,并在转换过程中改变颜色。它可以用于提亮图像、增加对比度或甚至将图像转换为灰度图。

为了演示 RGBImageFilter ,下面将介绍一个使用动态插件策略进行图像处理过滤的示例,包括 ImageFilterDemo 主 applet 类、 PlugInFilter 接口、 LoadedImage 实用类,以及 Grayscale Invert Contrast Blur Sharpen 等过滤器类。

4.2.1 ImageFilterDemo 类

ImageFilterDemo 类是示例图像过滤器的 applet 框架。它使用简单的 BorderLayout ,在南部位置放置一个面板来容纳表示每个过滤器的按钮,北部位置放置一个 Label 对象用于显示过滤器进度的信息,中心位置放置图像。

/*
 * <applet code=ImageFilterDemo width=400 height=345>
 * <param name=img value=Lilies.jpg>
 * <param name=filters value="Grayscale+Invert+Contrast+Blur+Sharpen">
 * </applet>
 */
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class ImageFilterDemo extends Applet implements ActionListener {
    Image img;
    PlugInFilter pif;
    Image fimg;
    Image curImg;
    LoadedImage lim;
    Label lab;
    Button reset;

    public void init() {
        setLayout(new BorderLayout());
        Panel p = new Panel();

        add(p, BorderLayout.SOUTH);
        reset = new Button("Reset");
        reset.addActionListener(this);
        p.add(reset);
        StringTokenizer st = new StringTokenizer(getParameter("filters"), "+");

        while (st.hasMoreTokens()) {
            Button b = new Button(st.nextToken());
            b.addActionListener(this);
            p.add(b);
        }

        lab = new Label("");
        add(lab, BorderLayout.NORTH);

        img = getImage(getDocumentBase(), getParameter("img"));
        lim = new LoadedImage(img);
        add(lim, BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent ae) {
        String a = "";

        try {
            a = ae.getActionCommand();
            if (a.equals("Reset")) {
                lim.set(img);
                lab.setText("Normal");
            } else {
                pif = (PlugInFilter) Class.forName(a).newInstance();
                fimg = pif.filter(this, img);
                lim.set(fimg);
                lab.setText("Filtered: " + a);
            }
            repaint();
        } catch (ClassNotFoundException e) {
            lab.setText(a + " not found");
            lim.set(img);
            repaint();
        } catch (InstantiationException e) {
            lab.setText("couldn’t new " + a);
        } catch (IllegalAccessException e) {
            lab.setText("no access: " + a);
        }
    }
}

操作步骤:

  1. 初始化 applet,设置布局和按钮。
  2. 解析过滤器名称。
  3. 加载图像。
  4. 处理按钮点击事件,根据按钮标签加载相应的过滤器类。
  5. 应用过滤器并更新显示。
4.2.2 PlugInFilter 接口

PlugInFilter 是一个简单的接口,用于抽象图像过滤。它只有一个方法 filter() ,接受 applet 和源图像,并返回经过某种过滤的新图像。

interface PlugInFilter {
    java.awt.Image filter(java.applet.Applet a, java.awt.Image in);
}
4.2.3 LoadedImage 类

LoadedImage Canvas 的一个方便子类,它在构造时接受一个图像,并使用 MediaTracker 同步加载它。它还提供了 set() 方法,用于设置要在该 Canvas 中显示的新图像。

import java.awt.*;

public class LoadedImage extends Canvas {
    Image img;

    public LoadedImage(Image i) {
        set(i);
    }

    void set(Image i) {
        MediaTracker mt = new MediaTracker(this);
        mt.addImage(i, 0);
        try {
            mt.waitForAll();
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
            return;
        }
        img = i;
        repaint();
    }

    public void paint(Graphics g) {
        if (img == null) {
            g.drawString("no image", 10, 30);
        } else {
            g.drawImage(img, 0, 0, this);
        }
    }

    public Dimension getPreferredSize() {
        return new Dimension(img.getWidth(this), img.getHeight(this));
    }

    public Dimension getMinimumSize() {
        return getPreferredSize();
    }
}

操作步骤:

  1. 创建 LoadedImage 对象,传入图像。
  2. 使用 set() 方法设置新图像。
  3. 自动加载图像并重新绘制。
4.2.4 具体过滤器类

以下是几个具体的过滤器类示例:

Grayscale 类
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

class Grayscale extends RGBImageFilter implements PlugInFilter {
    public Image filter(Applet a, Image in) {
        return a.createImage(new FilteredImageSource(in.getSource(), this));
    }

    public int filterRGB(int x, int y, int rgb) {
        int r = (rgb >> 16) & 0xff;
        int g = (rgb >> 8) & 0xff;
        int b = rgb & 0xff;
        int k = (int) (.56 * g + .33 * r + .11 * b);
        return (0xff000000 | k << 16 | k << 8 | k);
    }
}
Invert 类
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

class Invert extends RGBImageFilter implements PlugInFilter {
    public Image filter(Applet a, Image in) {
        return a.createImage(new FilteredImageSource(in.getSource(), this));
    }

    public int filterRGB(int x, int y, int rgb) {
        int r = 0xff - (rgb >> 16) & 0xff;
        int g = 0xff - (rgb >> 8) & 0xff;
        int b = 0xff - rgb & 0xff;
        return (0xff000000 | r << 16 | g << 8 | b);
    }
}
Contrast 类
import java.applet.*;
import java.awt.*;
import java.awt.image.*;

public class Contrast extends RGBImageFilter implements PlugInFilter {

    public Image filter(Applet a, Image in) {
        return a.createImage(new FilteredImageSource(in.getSource(), this));
    }

    private int multclamp(int in, double factor) {
        in = (int) (in * factor);
        return in > 255 ? 255 : in;
    }

    double gain = 1.2;
    private int cont(int in) {
        return (in < 128) ? (int) (in / gain) : multclamp(in, gain);
    }

    public int filterRGB(int x, int y, int rgb) {
        int r = cont((rgb >> 16) & 0xff);
        int g = cont((rgb >> 8) & 0xff);
        int b = cont(rgb & 0xff);
        return (0xff000000 | r << 16 | g << 8 | b);
    }
}

4.3 表格:过滤器类功能总结

过滤器类 功能描述
Grayscale 将图像转换为灰度图。
Invert 反转图像的颜色。
Contrast 增强图像的对比度。
Blur 对图像进行模糊处理。
Sharpen 对图像进行锐化处理。

4.4 流程图:图像过滤流程

graph TD;
    A[加载图像] --> B[选择过滤器];
    B --> C[应用过滤器];
    C --> D[显示过滤后的图像];

通过以上介绍,我们了解了 Java 中图像编程的多个方面,包括图像加载、生成、像素抓取和过滤等。这些技术可以帮助我们实现各种图像处理任务,如创建自定义图像、提取图像区域、改变图像颜色和增强图像效果等。希望这些内容对你有所帮助,你可以根据自己的需求进一步探索和应用这些技术。

5. 卷积过滤器相关类

5.1 Convolver 抽象类

Convolver 是一个抽象类,它实现了 ImageConsumer 接口,用于处理卷积过滤器的基本操作。它将源像素移动到一个名为 imgpixels 的数组中,并创建另一个名为 newimgpixels 的数组来存储过滤后的数据。卷积过滤器会对图像中每个像素周围的一个小矩形区域(即卷积核)进行采样,以此决定如何改变该区域的中心像素。

import java.applet.*;
import java.awt.*;
import java.awt.image.*;

abstract class Convolver implements ImageConsumer, PlugInFilter {
    int width, height;
    int imgpixels[], newimgpixels[];
    boolean imageReady = false;

    abstract void convolve(); // 具体的过滤操作

    public Image filter(Applet a, Image in) {
        imageReady = false;
        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 {
            while(!imageReady) wait();
        } catch (Exception e) {
            System.out.println("Interrupted");
        }
    }

    public void setProperties(java.util.Hashtable<?,?> dummy) { }
    public void setColorModel(ColorModel dummy) { }
    public void setHints(int dummy) { }

    public synchronized void imageComplete(int dummy) {
        imageReady = true;
        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) {
        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;
        }
    }
}

操作步骤:

  1. 实现 convolve() 抽象方法,定义具体的卷积过滤操作。
  2. filter() 方法中,启动图像生产,等待图像准备好,创建存储过滤后数据的数组,调用 convolve() 方法进行过滤,最后创建并返回过滤后的图像。

5.2 Blur 类

Blur 类是 Convolver 的子类,它对源图像数组 imgpixels 中的每个像素进行遍历,计算其周围 3x3 区域的平均值,并将该平均值作为 newimgpixels 中对应输出像素的值。

public class Blur extends Convolver {
    public void convolve() {
        for(int y=1; y<height-1; y++) {
            for(int x=1; x<width-1; x++) {
                int rs = 0;
                int gs = 0;
                int bs = 0;

                for(int k=-1; k<=1; k++) {
                    for(int j=-1; j<=1; j++) {
                        int rgb = imgpixels[(y+k)*width+x+j];
                        int r = (rgb >> 16) & 0xff;
                        int g = (rgb >> 8) & 0xff;
                        int b = rgb & 0xff;
                        rs += r;
                        gs += g;
                        bs += b;
                    }
                }

                rs /= 9;
                gs /= 9;
                bs /= 9;

                newimgpixels[y*width+x] = (0xff000000 |
                        rs << 16 | gs << 8 | bs);
            }
        }
    }
}

5.3 Sharpen 类

Sharpen 类也是 Convolver 的子类,它与 Blur 类大致相反。它遍历源图像数组 imgpixels 中的每个像素,计算其周围 3x3 区域(不包括中心像素)的平均值,然后将中心像素与周围平均值的差值加到中心像素上,作为 newimgpixels 中对应输出像素的值。这样可以突出图像的边缘,同时保持平滑区域不变。

public class Sharpen extends Convolver {

    private final int clamp(int c) {
        return (c > 255 ? 255 : (c < 0 ? 0 : c));
    }

    public void convolve() {
        int r0=0, g0=0, b0=0;

        for(int y=1; y<height-1; y++) {
            for(int x=1; x<width-1; x++) {
                int rs = 0;
                int gs = 0;
                int bs = 0;

                for(int k=-1; k<=1; k++) {
                    for(int j=-1; j<=1; j++) {
                        int rgb = imgpixels[(y+k)*width+x+j];
                        int r = (rgb >> 16) & 0xff;
                        int g = (rgb >> 8) & 0xff;
                        int b = rgb & 0xff;
                        if (j == 0 && k == 0) {
                            r0 = r;
                            g0 = g;
                            b0 = b;
                        } else {
                            rs += r;
                            gs += g;
                            bs += b;
                        }
                    }
                }

                rs >>= 3;
                gs >>= 3;
                bs >>= 3;
                newimgpixels[y*width+x] = (0xff000000 |
                        clamp(r0+r0-rs) << 16 |
                        clamp(g0+g0-gs) << 8 |
                        clamp(b0+b0-bs));
            }
        }
    }
}

5.4 表格:卷积过滤器类对比

过滤器类 操作方式 效果
Blur 计算每个像素 3x3 区域的平均值 模糊图像
Sharpen 计算每个像素 3x3 区域(不包括中心)的平均值,用中心像素与平均值的差值调整中心像素 锐化图像,突出边缘

5.5 流程图:卷积过滤流程

graph TD;
    A[加载源图像] --> B[初始化 Convolver];
    B --> C[将源像素存入 imgpixels 数组];
    C --> D[选择具体卷积子类(Blur 或 Sharpen)];
    D --> E[执行 convolve() 方法];
    E --> F[将过滤后数据存入 newimgpixels 数组];
    F --> G[创建并返回过滤后的图像];

6. 总结

通过上述内容,我们全面了解了 Java 中图像编程的丰富知识和技术。从图像的加载与跟踪开始,我们学会了如何确保图像正确加载并进行显示。 ImageProducer ImageConsumer 接口及其具体实现类 MemoryImageSource PixelGrabber ,让我们能够生成自定义图像和抓取现有图像的像素数据。

ImageFilter 类及其子类为我们提供了强大的图像处理能力,包括提取图像区域、改变图像颜色和增强图像效果等。其中, CropImageFilter 可以方便地从大图像中提取小图像, RGBImageFilter 能够逐像素地对图像进行颜色转换。动态插件策略的引入,使得我们可以根据需要灵活加载不同的过滤器,实现多样化的图像处理需求。

卷积过滤器相关类 Convolver 及其子类 Blur Sharpen ,则为我们提供了更高级的图像处理功能,能够对图像进行模糊和锐化处理,突出图像的特征。

在实际应用中,我们可以根据具体需求选择合适的技术和过滤器,实现各种复杂的图像处理任务。例如,在游戏开发中,可以使用图像过滤技术实现特效;在图像处理软件中,可以利用卷积过滤器增强图像的质量。希望这些知识能够帮助你在 Java 图像编程领域取得更好的成果。

6.1 操作步骤总结

  • 图像加载与跟踪 :创建 MediaTracker ,添加图像,检查加载状态。
  • 图像生成 :使用 MemoryImageSource ,创建像素数组,生成图像。
  • 像素抓取 :使用 PixelGrabber ,创建数组,抓取像素数据。
  • 图像过滤 :选择合适的过滤器类,应用过滤器,显示过滤后的图像。
  • 卷积过滤 :继承 Convolver 类,实现 convolve() 方法,进行卷积操作。

6.2 技术点回顾表格

技术点 相关类/接口 作用
图像加载与跟踪 MediaTracker 确保图像正确加载
图像生成 ImageProducer MemoryImageSource 生成自定义图像
像素抓取 ImageConsumer PixelGrabber 抓取现有图像的像素数据
图像过滤 ImageFilter 及其子类 对图像进行各种处理
卷积过滤 Convolver 及其子类 实现图像的模糊和锐化

通过不断实践和探索,你可以进一步挖掘 Java 图像编程的潜力,创造出更加精彩的图像处理应用。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值