java.awt.image.BufferedImage使用自定义ColorSpace的24位RGB到8位灰度转换

我想用java.awt.image.BufferedImage做一个简单的灰度转换颜色。我是图像处理领域的初学者,所以请原谅,如果我困惑的东西。我想在输出上获得一个8位灰度BufferedImage,这意味着我有一个这样的类(为了清楚起见,细节被省略):我的输入图像是RGB 24位图像(无alpha),我想在输出上获得8位灰度BufferedImage,java.awt.image.BufferedImage使用自定义ColorSpace的24位RGB到8位灰度转换

public class GrayscaleFilter { 

private BufferedImage colorFrame;

private BufferedImage grayFrame =

new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);

我已经成功地尝试了2种转换的方法到现在为止,第一个是:

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,这对我来说效果不佳,据我所知,但我不确定,我只是假设使用这些值)。第二种方法工作较慢,但效果非常好。

有没有一种方法来结合这两个,例如。使用自定义索引ColorSpaceColorConvertOp?如果是,请给我举个例子吗?

在此先感谢。

回答:

尝试修改你的第二种方法。而不是在一个像素上工作,检索一个argb int值的数组,将其转换并设置回来。

回答:

有一个示例here,它与第一个示例在一个小方面不同,参数为ColorConvertOp。尝试:

protected void filter() { 

BufferedImageOp grayscaleConv =

new ColorConvertOp(colorFrame.getColorModel().getColorSpace(),

grayFrame.getColorModel().getColorSpace(), null);

grayscaleConv.filter(colorFrame, grayFrame);

}

回答:

public BufferedImage getGrayScale(BufferedImage inputImage){ 

BufferedImage img = new BufferedImage(inputImage.getWidth(), inputImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY);

Graphics g = img.getGraphics();

g.drawImage(inputImage, 0, 0, null);

g.dispose();

return img;

}

回答:

第二种方法是基于像素的亮度,因此其获得更有利的视觉效果。当使用查找数组或哈希表计算l时,可以通过优化昂贵的浮点算术运算来加快速度。

回答:

这是一种在某些情况下适用于我的解决方案。

获取图像高度y,图像宽度x,图像颜色深度m和整数位大小n。仅在(2^m)/(x * y * 2^n)> = 1时起作用。 在处理初始灰度值时,为每个颜色通道保留一个n位整数。将每个通道的平均值avr [通道]的总和除以(x * y)。将每个通道的每个像素添加(192-avr [通道])。

请记住,这种做法可能不会有质量为标准亮度的方法相同的水平,但如果你正在寻找速度和质量之间的妥协,而不想对付昂贵的浮点操作,它可能适合你。

以上是 java.awt.image.BufferedImage使用自定义ColorSpace的24位RGB到8位灰度转换 的全部内容, 来源链接: utcz.com/qa/264906.html

回到顶部