简体   繁体   中英

Reading pixels from images using Java

I'm trying to convert from RGB to GrayScale Image.

The method that does this task is the following:

public BufferedImage rgbToGrayscale(BufferedImage in)
{
    int width = in.getWidth();
    int height = in.getHeight();

    BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    WritableRaster raster = grayImage.getRaster();

    int [] rgbArray = new int[width * height];      
    in.getRGB(0, 0, width, height, rgbArray, 0, width);

    int [] outputArray = new int[width * height];
    int red, green, blue, gray;

    for(int i = 0; i < (height * width); i++)
    {
        red = (rgbArray[i] >> 16) & 0xff;
        green = (rgbArray[i] >> 8) & 0xff;
        blue = (rgbArray[i]) & 0xff;

        gray = (int)( (0.30 * red) + (0.59 * green) + (0.11 * blue));                        

        if(gray < 0)
            gray = 0;
        if(gray > 255)
            gray = 255;

        outputArray[i] = (gray & 0xff);           
        }
    }
    raster.setPixels(0, 0, width, height, outputArray);     

    return grayImage;       
}

I have a method that saves the pixels value in a file:

public void writeImageValueToFile(BufferedImage in, String fileName)
{
    int width = in.getWidth();
    int height = in.getHeight();

    try
    {
        FileWriter fstream = new FileWriter(fileName + ".txt");
        BufferedWriter out = new BufferedWriter(fstream);

        int [] grayArray = new int[width * height];     
        in.getRGB(0, 0, width, height, grayArray, 0, width);

        for(int i = 0; i < (height * width); i++)
        {                       
            out.write((grayArray[i] & 0xff) + "\n");                                
        }

        out.close();
    } catch (Exception e)
    {
        System.err.println("Error: " + e.getMessage());
    }
}

The problem that I have is that, the RGB value I get from my method, is always bigger than the expected one.

I created an image and I filled it with color 128, 128, 128. According to the first method, if I print the outputArray's data, I get:
r, g, b = 128, 128, 128. Final = 127 ---> correct :D

However, when I called the second method, I got the RGB value 187 which is incorrect.

Any suggestion?

Thanks!!!

Take a look at javax.swing.GrayFilter , it uses the RBGImageFilter class to accomplish the same thing and has very similar implementation. It may make your life simpler.

I'm not an expert at these things but aren't RGB values stored as hex (base16)? If so, theproblem lies in your assumption that the operation & 0xff will cause your int to be stored/handled as base16. It is just a notation and default int usage in strings will always be base10.

    int a = 200;
    a = a & 0xff;
    System.out.println(a);

    // output
    200

You need to use an explicit base16 toString() method.

    System.out.println(Integer.toHexString(200));

    // output
    c8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM