2009-05-20 38 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分量的最大灰度。

相關問題