2

我知道可以使用将图像转换为 CS_GRAY

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

    return sourceImgGray;
}

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

有没有人知道如何使用 for 循环并假设图像是 RGB 颜色空间?

4

2 回答 2

3

ColorConvertOp.filter接受两个参数。第二个参数也是 a BufferedImage,它将是目的地。如果您将正确的方法传递BufferedImage给该filter方法,它将使您免于创建新的BufferedImage.

于 2010-05-10T17:08:21.013 回答
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 分量的最大值的灰度。

于 2014-06-09T23:05:17.153 回答