Read in Bufferedimage pixel values then manipulate each one and write to file

1.1k views Asked by At

I am currently trying to read in an image pixel by pixel and change each colored pixel to the rgb value of (100,100,100). For whatever reason when I check the values of each pixel one the image is saved it has all the colored pixels as (46,46,46) instead.

Here is the original image

enter image description here

After running my program this is the image it gives to me

enter image description here

Here is the code

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Cmaps {
    public static void main(String[] args){
        File originalImage = new File("C:\\Users\\Me\\Desktop\\0005.bmp");
        BufferedImage img = null;
        try{
            img = ImageIO.read(originalImage);
            for(int i = 0; i < img.getHeight(); i++){
                for(int j = 0; j < img.getWidth(); j++){
                    //get the rgb color of the image and store it
                    Color c = new Color(img.getRGB(i, j));
                    int r = c.getRed();
                    int g = c.getGreen();
                    int b = c.getBlue();
                    //if the pixel is white then leave it alone
                    if((r == 255) && (g == 255) && (b == 255)){
                        img.setRGB(i, j, c.getRGB());
                        continue;
                    }
                    //set the colored pixel to 100,100,100
                    r = 100;// red component 0...255
                    g = 100;// green component 0...255
                    b = 100;// blue component 0...255
                    int col = (r << 16) | (g << 8) | b;
                    img.setRGB(i, j, col);
                }
            }
            File f = new File("C:\\Users\\Me\\Desktop\\2\\1.png");
            try {
                ImageIO.write(img, "PNG", f);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (IOException e){
            e.printStackTrace();
        }
    }
}

I have no clue why it doesn't set the pixels to the expected rgb value. I eventually want to be able to basically increment the rgb color as I move down rows and columns in the x and y so what the final image will look like is it will start off dark in the top left corner and then have a fade out effect as you get from that side to the bottom right corner.

1

There are 1 answers

0
Harald K On BEST ANSWER

Okay, based on the comments:

If the BufferedImage has an IndexColorModel (palette based color model), using setRGB to set a pixel to an arbitrary RGB value will not work. Instead, the color will be looked up, and the pixel will get the color that is considered the closest match in the palette.

Formats like BMP, GIF and PNG may all use IndexColorModel when read using ImageIO.

To convert the image to "true color" (either DirectColorModel or ComponentColorModel in Java will do), you can use:

BufferedImage img; // your original palette image

int w = img.getWidth();
int h = img.getHeight();
BufferedImage trueColor = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

Graphics2D g = trueColor.createGraphics();
try {
    g.drawImage(img, 0, 0, null);
}
finally {
    g.dispose();
}

img = trueColor;

After this, getRGB(x, y) should return what you specify, using setRGB(x, y, argb).