简体   繁体   English

使用ImageIO.write将其保存为PNG文件后,奇怪的颜色更改为BufferedImage

[英]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. 我一直在尝试制作一个Java程序,该程序将允许某些像素颜色在BufferedImage更改为其他颜色,但是正在绘制的颜色似乎覆盖了旧的颜色。 Here's what I mean: 这就是我的意思:

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

This is the code that's on the .java file at the moment: 这是目前在.java文件中的代码:

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. 也许是setRGB()或类似的东西。

You are trying to create a PNG file, but this line... 您正在尝试创建PNG文件,但此行...

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

...is trying to write a JPEG. ...正在尝试编写JPEG。 According to the Unix file command, the output is indeed a JPEG... also with a bad case of dark cyan pixels. 根据Unix file命令,输出确实是JPEG ...,也带有暗青色像素的坏情况。

When I changed "jpg" to "png" , I got an output.png file that looked exactly the same as input.png . 当我将"jpg"更改为"png" ,得到了一个output.png文件,该文件看上去与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. 我不知道您希望输出看起来像什么(并且我使用的是不同的输入文件 ),但这似乎比JPEG-in-PNG的衣服颜色差。


Your log will be useless for debugging, because printPixelData always prints the values in pixelStorage . 你的日志将是无用的调试,因为printPixelData始终打印中的值pixelStorage Since setPixelData only changes the values in image , you will always print the "before" values twice, and never the "after" values. 由于setPixelData仅更改image的值,因此您将始终打印两次“ before”值,而永远不会打印“ after”值。

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 ). 至少将您可以使用的方法移动到方法中(例如heightwidthfile ,这些方法永远不会在main之外使用),然后删除根本不用的方法(例如getPixelDataOutputrandom )。


Probably unrelated, but the setPixelData method sets a pixel, and then immediately resets it to some other value: 可能不相关,但是setPixelData方法设置像素,然后立即将其重置为其他值:

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. 这似乎并没有改变任何东西---(无论是否第一次调用setRGB我的测试图像看起来都一样---但它可能不是您想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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