使用 ImageIO.write 将 BufferedImage 保存为 PNG 文件后颜色发生奇怪变化
Strange color changes to a BufferedImage after saving it as a PNG file with ImageIO.write
我一直在尝试制作一个 Java 程序,允许在 BufferedImage
中将某些像素颜色更改为其他颜色,但正在绘制的颜色似乎被覆盖了在旧的。这就是我的意思:
这是目前在 .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;
}
我不知道为什么会输出这样的图像。也许是 setRGB()
或类似的东西。
您正在尝试创建一个 PNG 文件,但是这一行...
ImageIO.write(image, "jpg", file);
...正在尝试编写 JPEG。
根据 Unix file
命令,输出确实是一个 JPEG...
还有深青色像素的坏情况。
当我将 "jpg"
更改为 "png"
时,我得到了一个看起来与 input.png
.
完全相同的 output.png
文件
我不知道你想要输出的样子
(我正在使用
different input file)
但这似乎比颜色错误的 JPEG-in-PNG 服装更接近。
您的日志对调试没有用,因为 printPixelData
总是打印 pixelStorage
中的值。
由于 setPixelData
仅更改 image
中的值,您将始终打印两次 "before" 值,而永远不会打印 "after" 值。
顺便说一句,所有这些静态变量使得跟踪程序的执行比它必须的要难得多。
至少将你能做的转移到方法中
(如 height
、width
和 file
,它们从未在 main
之外使用),
并删除您根本不使用的那些
(比如 getPixelDataOutput
和 random
)。
可能无关,但 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());
}
这似乎没有任何改变 ---
(无论是否第一次调用 setRGB
,我的测试图像看起来都一样 ---
但这可能不是你想要的。
我一直在尝试制作一个 Java 程序,允许在 BufferedImage
中将某些像素颜色更改为其他颜色,但正在绘制的颜色似乎被覆盖了在旧的。这就是我的意思:
这是目前在 .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;
}
我不知道为什么会输出这样的图像。也许是 setRGB()
或类似的东西。
您正在尝试创建一个 PNG 文件,但是这一行...
ImageIO.write(image, "jpg", file);
...正在尝试编写 JPEG。
根据 Unix file
命令,输出确实是一个 JPEG...
还有深青色像素的坏情况。
当我将 "jpg"
更改为 "png"
时,我得到了一个看起来与 input.png
.
output.png
文件
我不知道你想要输出的样子 (我正在使用 different input file) 但这似乎比颜色错误的 JPEG-in-PNG 服装更接近。
您的日志对调试没有用,因为 printPixelData
总是打印 pixelStorage
中的值。
由于 setPixelData
仅更改 image
中的值,您将始终打印两次 "before" 值,而永远不会打印 "after" 值。
顺便说一句,所有这些静态变量使得跟踪程序的执行比它必须的要难得多。
至少将你能做的转移到方法中
(如 height
、width
和 file
,它们从未在 main
之外使用),
并删除您根本不使用的那些
(比如 getPixelDataOutput
和 random
)。
可能无关,但 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());
}
这似乎没有任何改变 ---
(无论是否第一次调用 setRGB
,我的测试图像看起来都一样 ---
但这可能不是你想要的。