简体   繁体   中英

Strange color changes to a BufferedImage after saving it as a PNG file with ImageIO.write

I've been trying to make a Java program that will allow some pixel colors to be changed to other colors in a BufferedImage , but the colors that are being drawn seem to be overlaid over the old ones. Here's what I mean:

input.png和output.png的组合图像

This is the code that's on the .java file at the moment:

static BufferedImage image = null;
static File file = null;
static int height;
static int width;
static int[][][] pixelStorage;
static int pixel;
static int getPixelDataOutput = 0;
static Random random = new Random();

public static void main(String args[]) throws IOException {

    System.out.println("test");

    try {
        file = new File("C:\\Users\\kkosy\\Dev\\Java\\Random\\Images - Color Changer\\Images\\input.png");
    }catch(Exception exception) {
        System.out.println(exception);
    }

    image = ImageIO.read(file);

    height = image.getHeight();
    width = image.getWidth();

    pixelStorage = new int[height][width][4];

    for(int h = 0; h < height - 1; h++) {
        for(int w = 0; w < width - 1; w++) {
            savePixelData(w, h);
            if(getPixelData(w,h,"r") == 0){
                System.out.println();
                printPixelData(w,h,"Before -- ");
                setPixelData(w,h,255,0,0,255);
                printPixelData(w,h,"After -- ");
            }
        }
    }

    try {
        file = new File("C:\\Users\\kkosy\\Dev\\Java\\Random\\Images - Color Changer\\Images\\output.png");
        ImageIO.write(image, "jpg", file);
    }catch(Exception exception){
        System.out.println(exception);
    }

}

private static void savePixelData(int x, int y) {
    pixel = image.getRGB(x,y);
    pixelStorage[y][x][0] = (pixel >> 24) & 0xff;
    pixelStorage[y][x][1] = (pixel >> 16) & 0xff;
    pixelStorage[y][x][2] = (pixel >> 8) & 0xff;
    pixelStorage[y][x][3] = pixel & 0xff;
    //printPixelData(x,y,"");

}

private static void setPixelData(int x, int y, int alpha, int red, int green, int blue) {
    int setPixel = (alpha << 24) | (red << 16) | (green << 8) | (blue);
    image.setRGB(x, y, setPixel);
    image.setRGB(x, y, new Color(red,green,blue).getRGB());
}

private static void printPixelData(int x, int y, String arguments) {
    System.out.println(arguments + "" + pixelStorage[y][x][0] + " " + pixelStorage[y][x][1] + " " + pixelStorage[y][x][2] + " " + pixelStorage[y][x][3] + " ");
}

private static int getPixelData(int x, int y, String argb) {
    switch(argb) {
    case "a": {
        getPixelDataOutput = pixelStorage[y][x][0];
        break;
    }
    case "r": {
        getPixelDataOutput = pixelStorage[y][x][1];
        break;
    }
    case "g": {
        getPixelDataOutput = pixelStorage[y][x][2];
        break;
    }
    case "b": {
        getPixelDataOutput = pixelStorage[y][x][3];
        break;
    }
    }
    return getPixelDataOutput;
}

I have no idea why it outputs such an image. Perhaps it's the setRGB() or something along those lines.

You are trying to create a PNG file, but this line...

ImageIO.write(image, "jpg", file);

...is trying to write a JPEG. According to the Unix file command, the output is indeed a JPEG... also with a bad case of dark cyan pixels.

When I changed "jpg" to "png" , I got an output.png file that looked exactly the same as input.png .

I don't know what you want the output to look like (and I'm using a different input file ) but this seems closer than the miscolored JPEG-in-PNG's-clothing.


Your log will be useless for debugging, because printPixelData always prints the values in pixelStorage . Since setPixelData only changes the values in image , you will always print the "before" values twice, and never the "after" values.

As an aside, all those static variables make tracing the program's execution much harder than it has to be. At least move what you can into methods (like height , width , and file , which are never used outside of main ), and delete the ones you don't use at all (like getPixelDataOutput and random ).


Probably unrelated, but the setPixelData method sets a pixel, and then immediately resets it to some other value:

private static void setPixelData(
  int x, int y,
  int alpha, int red, int green, int blue
) {
    int setPixel = (alpha << 24) | (red << 16) | (green << 8) | (blue);
    image.setRGB(x, y, setPixel);
    // Why overwrite the value you just set?
    image.setRGB(x, y, new Color(red,green,blue).getRGB());
}

This doesn't seem to change anything --- (my test image looked the same with or without the first call to setRGB --- but it's probably not what you wanted.

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