1、使用常规的图像过滤器
使用图像过滤器的一般步骤:
- 实例化图像过滤器。
- 实例化FilteredImageSource,并将它传递给和原图像相关联的图像生产者和过滤器。
- 调用createImage ()方法,并将它传递给FilterlmageSourceo
FilterImageSource
类扩展ImageProducer
,并且可以保持原图像,过滤器用于过滤它。当被过滤的图像源被要求产生图像时,它将发送请求给原图像的图像生产者,设置过滤器为图像消费者。从而,原图像的生产者通过图像过滤器传输图像位,结果是被过滤后的图像。
2、ReplicateScaleFilter和AreaAveragingScaleFilter
ReplicateScaleFilter过滤器使用一个简单的算法缩放图像:复制图像数据的行或列进行放大,删除图像数据的行或列进行缩小。
例:
import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;
import java.io.IOException;
import java.net.URL;
public class demo06 extends Applet {
Image image;
Image copy;
int w,h;
@Override
public void init() {
MediaTracker mt = new MediaTracker(this);
URL codeBase = getClass().getResource("1.jpg");
try {
image = createImage((ImageProducer)codeBase.getContent());
mt.addImage(image,0);
mt.waitForID(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
w = image.getWidth(this);
h = image.getHeight(this);
System.out.println(w + "\n" + h);
ImageFilter rsf = new ReplicateScaleFilter(w/10,h/10);
FilteredImageSource fis = new FilteredImageSource(image.getSource(),rsf);
copy = createImage(fis);
}
public void paint(Graphics g){
g.drawImage(copy,250,0,this);
g.drawImage(image,0,0,200,200,this);
}
}
结果:
AreaAveragingScaleFilter
是 ReplicateScaleFilter
的一个扩展,它在缩放图像时采用了一个比较高级的算法。AreaAveragingScaleFilter
过滤器和ReplicateScaleFilter
过滤器的使用方式相同,但两者相比较而言,前者缩放图像的质量比后者要好。
然而,我们知道要得到较好的质量,就必然要花费一定的代价——AreaAveragingScaleFilter过滤器所花费的时间和ReplicateScaleFilter过滤器相比,要长得多。而且, AreaAveragingScaleFilter过滤器仅限于在可以用TDLR模式传输像素的图像生产者中使用。如果不能用TDLR模式传输像素,则 AreaAveragingScaleFilter过滤器则是求助于其超类ReplicateScaleFilter的算法。
3、组合图像过滤器
图像过滤器可以很容易地组合在一起,以生成对应的复合效果。
ImageFilter cif = new CropImageFilter(0, 0, 50, 50); //裁剪的矩形
FilteredImageSource fis = new FilteredImageSource(image.getSource(),cif);//封装
copy = createImage(fis);//创建图像
w = copy.getWidth(this);
h = copy.getHeight(this);
ImageFilter rsf = new ReplicateScaleFilter(w*10,h*10);
FilteredImageSource fis = new FilteredImageSource(copy.getSource(),rsf);
copy = createImage(fis)
4、ImageConsumer属性
ImageConsumer.setProperties ()
,它可以用来设置和图像消费者有关的属性。SetProperties ()
是一个非对称方法,因为它没有对应的getProperties ()
。这些设置的属性主要是作为调试技术,其典型的应用就是在调试器中进行查看。如果你希望查看和图像过滤器相关的那些属性,但又不希望采用调试器,则必须实现覆盖setProperties ()方法并且将属性打印出来的过滤器。
例:
class PropertiesReportingFilter extends ImageFilter {
public void setProperties (Hashtable ht) {
super.setProperties(ht);
System.out.println(ht);
}
}
5、自定义图像过滤器
在AWT 中,提供了两种方法用来实现自定义图像过滤器。
- 一个方法是扩展ImageFilter类,lmageFilter类是一个“null”过滤器,该过滤器在传输信息给另一个图像消费者时,不改变图像位的信息。就像你所想象的那样,一个图像过滤器如果没有改变原图像,其自身是没有什么用处的。ImageFilter类被子类化以实现实际修改原图像的过滤器。正像我们下面将要讲述的一样,扩展ImageFilter类有时可能是一个令人畏缩的任务。
- 另一种实现方法是扩展 RGBImageFilter类。RGBImageFilter扩展ImageFilter,和它的超类相比,该类是–个简单的子类。所以,我们将先讨论扩展RCBImageFilter 的图像过滤器,然后再讨论扩展ImageFilter类的过滤器。
6、扩展RGBImageFilter
RGBImageFilter
是一个抽象类,在该类中定义了下面一个抽象方法:
int filterRCB ( int x,int y,int rgb)
- 在缺省的RCB颜色模式中,向filterRGB ()传递像素的位置和像素的一个整数表示。该方法被用作检验像素的RGB表示法,返回相同的 RCB表示或被修改的像素颜色。
- 许多的图像过滤器只关心构成图像的像素颜色的改变,它们当然是和扩展RGBImageFilter类相匹配的候选者。
- 此外,从RGBImageFilter派生的图像过滤器的百分比,是只关心图像中颜色的使用,而对图像中每个像素的位置不感兴趣。例如漂白过滤,其作用是使图像中的每个像素变亮,而不会去关心每个像素在图像中的位置。这样做的结果是允许RGBImageFilter类进行更大的简化。
- 在RGBImageFilter类中,包含有一个protecd boolen 成员---- canFilterIndexColorModel。如果RGBImageFilter的一个扩展设置这个变量的值为true,则图像将不向过滤器传递图像中的每个像素,而扩展将传递图像中每个颜色的RCB表示。这种方法将会提高性能,尤其对大图像来讲。
两个由 RGBImageFilter派生的过滤器:溶解过滤器和边缘溶解过滤器
- 溶解过滤器的作用是改变图像中每个颜色的 alpha值,也就是说改变要过滤的图像的透明度。
- 边缘溶解过滤器改变图像边框像素的 alpha值,也就是说改变要过滤的图像边缘的透明度。
溶解过滤器可以过滤直接颜色模式,意味着它过滤的对象是图像的颜色,而不是针对图像中单个像素。另一方面,对于边缘溶解过滤器所关心的是图像中每个像素的位置,所以在过滤时是根据像素进行过滤而不是根据颜色。黑白过滤器的作用是将图像中的颜色滤掉,漂白过滤器的作用是使图像中的每个像素都变亮,而负值过滤器的作用是生产一个类似于照片负片的效果。
7、DissolveFilter
溶解过滤器
import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;
import java.io.IOException;
import java.net.URL;
public class demo06 extends Applet {
Image image;
Image copy;
int w,h;
@Override
public void init() {
MediaTracker mt = new MediaTracker(this);
URL codeBase = getClass().getResource("1.jpg");
try {
image = createImage((ImageProducer)codeBase.getContent());
mt.addImage(image,0);
mt.waitForID(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
ImageFilter rsf = new DissolveFilter(50);
FilteredImageSource fis = new FilteredImageSource(image.getSource(),rsf);
copy = createImage(fis);
}
public void paint(Graphics g){
g.drawImage(image,0,0,200,200,this);
g.drawImage(copy,250,0,200,200,this);
}
class DissolveFilter extends RGBImageFilter {
private int alpha;
public DissolveFilter() {
this(0);
}
public DissolveFilter(int alpha) {
canFilterIndexColorModel = true;
if(alpha < 0 || alpha > 255) {
throw new IllegalArgumentException("bad alpha");
}
this.alpha = alpha;
}
public int filterRGB(int x, int y, int rgb) {
DirectColorModel cm = (DirectColorModel) ColorModel.getRGBdefault();
int alpha = cm.getAlpha(rgb);
int red = cm.getRed(rgb);
int green = cm.getGreen(rgb);
int blue = cm.getBlue(rgb);
alpha = alpha == 0 ? 0 : this.alpha;
return alpha << 24 | red << 16 | green << 8 | blue;
}
}
}
结果: