преобразовать RGB-изображение в оттенки серого. Уменьшение памяти в Java - PullRequest
17 голосов
/ 03 февраля 2012

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

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

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

Ответы [ 3 ]

36 голосов
/ 03 февраля 2012

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

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);  

source: http://www.codebeach.com/2008/03/convert-color-image-to-gray-scale-image.html

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

23 голосов
/ 03 февраля 2012

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


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

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);

        // Normalize and gamma correct:
        float rr = Math.pow(r / 255.0, 2.2);
        float gg = Math.pow(g / 255.0, 2.2);
        float bb = Math.pow(b / 255.0, 2.2);

        // Calculate luminance:
        float lum = 0.2126 * rr + 0.7152 * gg + 0.0722 * bb;

        // Gamma compand and rescale to byte range:
        int grayLevel = (int) (255.0 * Math.pow(lum, 1.0 / 2.2));
        int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel; 
        img.setRGB(x, y, gray);
    }
}

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

2 голосов
/ 27 августа 2015

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...