2009-05-20 2 views
2

Я знаю, что его можно преобразовать изображение в CS_GRAY используяJava Преобразовать ColorSpace из BufferedImage в CS_GRAY без использования 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; 
} 

однако, это перегруженный всей моей программы. Мне нужно делать это часто, на изображениях 800x600 пикселей и занимает около 200-300 мсек для выполнения этой операции в среднем. Я знаю, что я могу сделать это намного быстрее, используя один цикл для циклического преобразования данных изображения и сразу же установив его. С другой стороны, код выше создает новый 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, в каждом из разделов.

Смежные вопросы