Конвертировать RGB-изображение в оттенки серого. Уменьшение объема памяти в java

У меня есть RGB bufferedImage bImg.
Я хочу преобразовать bImg в серое изображение.

BufferedImage grayIm=new BufferedImage(bImg.getWidth(null), bImg.getHeight(null), BufferedImage.TYPE_BYTE_GRAY); 

Я пробовал этот grayIm, но я не могу установить значения оттенков серого для этого grayIm.

Ответ 1

Одним из способов может быть преобразование цветового пространства (низкая производительность):

ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);  
ColorConvertOp op = new ColorConvertOp(cs, null);  
BufferedImage image = op.filter(bufferedImage, null);

Другим было бы использование BufferedImage, как и вы (более высокая производительность):

BufferedImage image = new BufferedImage(width, height,  
    BufferedImage.TYPE_BYTE_GRAY);  
Graphics g = image.getGraphics();  
g.drawImage(colorImage, 0, 0, null);  
g.dispose();  

И последнее, но не менее важное: лучшая производительность - использование GrayFilter:

ImageFilter filter = new GrayFilter(true, 50);  
ImageProducer producer = new FilteredImageSource(colorImage.getSource(), filter);  
Image mage = Toolkit.getDefaultToolkit().createImage(producer);  

источник: http://www.codebeach.com/2008/03/convert-color-image-to-gray-scale-image.html

изменить: за комментарий.

Ответ 2

ПРИМЕЧАНИЕ. Это не то, о чем попросил ОП (поскольку он не уменьшает использование памяти), но я оставлю его здесь, так как люди, подобные этому подходу на основе одного пикселя.


Это довольно просто. Идея состоит в том, чтобы перебирать каждый пиксель изображения и менять его на эквивалент в оттенках серого.

public static void makeGray(BufferedImage img)
{
    for (int x = 0; x < img.getWidth(); ++x)
    for (int y = 0; y < img.getHeight(); ++y)
    {
        int rgb = img.getRGB(x, y);
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = (rgb & 0xFF);

        int grayLevel = (r + g + b) / 3;
        int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel; 
        img.setRGB(x, y, gray);
    }
}

Однако это не уменьшает память. Чтобы эффективно сократить использование памяти, выполните один и тот же процесс, но используйте вывод BufferedImage в градациях серого.

Ответ 3

У меня была такая же проблема. Решение, которое вы выбираете, зависит не только от уровня производительности. Также необходимо понять, какое качество изображения вы стремитесь. Посмотрите на эти примеры. Все они поддерживают исходный код. http://codehustler.org/blog/java-to-create-grayscale-images-icons/