我想使用 java.awt.image.BufferedImage
进行简单的彩色图像转灰度处理。我在图像处理领域是个初学者,如果我混淆了什么,请见谅。
我的输入图像是RGB 24位图像(没有α通道),我希望输出一个8位灰度BufferedImage
,这意味着我有一个类似于这样的类(为了清晰起见,详情被省略):
public class GrayscaleFilter {
private BufferedImage colorFrame;
private BufferedImage grayFrame =
new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
到目前为止,我已经成功尝试了两种转换方法,第一种是:
private BufferedImageOp grayscaleConv =
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
protected void filter() {
grayscaleConv.filter(colorFrame, grayFrame);
}
第二点是:
protected void filter() {
WritableRaster raster = grayFrame.getRaster();
for(int x = 0; x < raster.getWidth(); x++) {
for(int y = 0; y < raster.getHeight(); y++){
int argb = colorFrame.getRGB(x,y);
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb ) & 0xff;
int l = (int) (.299 * r + .587 * g + .114 * b);
raster.setSample(x, y, 0, l);
}
}
}
第一种方法速度更快,但生成的图像非常暗,这意味着我正在失去带宽,这是不可接受的(在灰度和sRGB ColorModel之间使用了一些颜色转换映射,称为tosRGB8LUT,对我来说效果不佳,我只是猜测这些值被使用)。第二种方法速度较慢,但效果非常好。
有没有一种方法可以将这两种方法结合起来,例如使用自定义索引的ColorSpace用于ColorConvertOp?如果有,请给我一个例子。
提前致谢。