2009-05-20 40 views
2

到CS_GRAY我知道它可以将图像转换使用的Java转换色彩空间而不使用ConvertColorOp

public static BufferedImage getGrayBufferedImage(BufferedImage image) { 
    BufferedImageOp op = new ColorConvertOp(ColorSpace 
      .getInstance(ColorSpace.CS_GRAY), null); 
    BufferedImage sourceImgGray = op.filter(image, null); 

    return sourceImgGray; 
} 

然而CS_GRAY,这是我整个程序的阻塞点。我需要经常这样做,在800x600像素的图像上,平均需要大约200-300ms才能完成此操作。我知道我可以更快地做到这一点,通过使用一个循环来遍历图像数据并立即设置它。另一方面,上面的代码构造了一个全新的800x600 BufferedImage,它是灰度级的。我宁愿只是转换我通过的图像。

是否有人知道如何使用for循环执行此操作,并且该图像是RGB色彩空间?

回答

2

ColorConvertOp.filter需要两个参数。第二个参数也是BufferedImage,它将成为目的地。如果您将正确的BufferedImage传递给filter方法,您可以省去麻烦,创建新的BufferedImage

1
private static int grayscale(int rgb) { 
    int r = rgb >> 16 & 0xff; 
    int g = rgb >> 8 & 0xff; 
    int b = rgb  & 0xff; 
    int cmax = Math.max(Math.max(r, g),b); 
    return (rgb & 0xFF000000) | (cmax << 16) | (cmax << 8) | cmax; 
} 
public static BufferedImage grayscale(BufferedImage bi) { 
    BufferedImage bout = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB); 
    int[] rgbArray = new int[bi.getWidth() * bi.getHeight()]; 
    rgbArray = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), rgbArray, 0, bi.getWidth()); 
    for (int i = 0, q = rgbArray.length; i < q; i++) { 
     rgbArray[i] = grayscale(rgbArray[i]); 
    } 
    bout.setRGB(0, 0, bout.getWidth(), bout.getHeight(), rgbArray, 0, bout.getWidth()); 
    return bout; 
} 

无论你在做什么,你都可能做错事。您不应该一次又一次地重新生成缓冲图像。但是,应该找出一个方案来简单地更新缓冲图像,或者从原始图像中取出原始像素,并在每个部分中仅使用RGB分量的最大灰度。

相关问题