Question

** Important update, see below! **

I am creating a program that changes the pixels of a BufferedImage to a certain color when that pixel fulfills a set of conditions in Java. However, when I write the image to disk, the pixels that should be colored are instead black.

First I define the color, using RGB codes:

Color purple = new Color(82, 0, 99);
int PURPLE = purple.getRGB();

Then I read the image I want to alter from a File into a BufferedImage called "blank":

BufferedImage blank = ImageIO.read(new File("some path"));

Now, loop through the pixels, and when a pixel at location (x, y) matches a criteria, change its color to purple:

blank.setRGB(x, y, PURPLE);

Now, write "blank" to the disk.

File output = new File("some other path");
ImageIO.write(blankIn, "png", output); // try-catch blocks intentionally left out

The resulting file should be "blank" with some purple pixels, but the pixels in question are instead black. I know for a fact that the issue is with setRGB and NOT any import or export functions, because "blank" itself is a color image, and gets written to file as such. I read around and saw a lot of posts recommending that I use Graphics2D and to avoid setRGB, but with no discussion of pixel-by-pixel color changing.

I also tried direct bit manipulation, like this:

blank.setRGB(x, y, ((82 << 16) + (0 << 8) + 99));

I'm probably doing that wrong, but if I put it in correctly it wouldn't matter, because the pixels are getting set to transparent when I do this (regardless of what the numbers say, which is very strange, to say the least).

** When I try this:

blank.setRGB(x, y, Color.RED.getRGB());

My output file is grayscale, so that means setRGB is, in fact, modifying my picture in grayscale. I think this is actually a rather simple issue, but the solution eludes me.

Was it helpful?

Solution

Based on the insights in https://stackoverflow.com/a/21981173 that you found yourself ... (a few minutes after posting the question) ... it seems that it should be sufficient to simply convert the image into ARGB directly after it was loaded:

public static BufferedImage convertToARGB(BufferedImage image)
{
    BufferedImage newImage = new BufferedImage(
        image.getWidth(), image.getHeight(),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = newImage.createGraphics();
    g.drawImage(image, 0, 0, null);
    g.dispose();
    return newImage;
}

OTHER TIPS

The original image that was imported into Java was actually grayscale, so when Java read it into the BufferedImage, it simply imported it as a grayscale BufferedImage. By adding a very small but imperceptible colored dot in the corner of my image, I was able to get Java to output a correctly colored image.

Unfortunately, this is only a half solution, because I do not know how to fix this programmatically.

SOLUTION: Convert the BufferedImage from grayscale to ARGB with this snippet:

BufferedImage blank2 = blank;
    // Create temporary copy of blank
blank = new BufferedImage(blank.getWidth(), blank.getHeight(), BufferedImage.TYPE_INT_ARGB);
    // Recreate blank as an ARGB BufferedImage
ColorConvertOp convert = new ColorConvertOp(null);
    // Now create a ColorConvertOp object
convert.filter(blank2, blank);
    // Convert blank2 to the blank color scheme and hold it in blank

You want to add this right after blank = ImageIO.read(new File("some path")).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top