convert a RGB image to grayscale Image reducing the memory in java

后端 未结 3 1430
粉色の甜心
粉色の甜心 2020-12-01 12:47

I have an RGB bufferedImage bImg .
I want to convert bImg to gray image.

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


        
相关标签:
3条回答
  • 2020-12-01 13:22

    I have had the same issue. The solution that you choose not only depends on the performance level. It is also necessary to understand whick image quality you strive for. Please look at these examples. They all maintain the source code. http://codehustler.org/blog/java-to-create-grayscale-images-icons/

    0 讨论(0)
  • 2020-12-01 13:32

    One way could be to convert the color space (poor performance):

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

    Another would be to use a BufferedImage, as you do (better performance):

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

    Last but not least, the best performance is using a 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: per Mark's comment.

    0 讨论(0)
  • NOTE: This is not what the OP asked for (since it does not reduce the memory usage), but I'll leave it here, since people like this manual per-pixel approach. Instead I'll show how to accurately calculate a grayscale color.


    This is quite simple. The idea is to iterate over each pixel of the image, and change it to its grayscale equivalent.

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

    However, this does not reduce memory. To effectively reduce the memory usage, do the same process but use a grayscale BufferedImage as output.

    0 讨论(0)
提交回复
热议问题