我正在做一些基于维基百科关于图像处理中的内核的页面的卷积矩阵图像滤波的基本实验。
为了计算RGB转换,我正在通过BufferedImage读取位图,然后用getRgb()获取像素。在测试最简单的标识过滤器时,我注意到对于特定的图片,我得到的是一些灰色而不是原始的黑色,而对于其他一些图片,黑色是可以的。
经过更多的测试后,我发现在没有任何转换的情况下,一个简单的BufferedImage -> int[] -> BufferedImage就会导致灰色结果。
我错过了什么?ImageMagick identify显示,两者都是没有alpha通道的8位256色图片.
betty1.png PNG 339x600 339x600+0+0 8-bit Gray 256c 24526B 0.000u 0:00.000
betty2.jpg JPEG 603x797 603x797+0+0 8-bit Gray 256c 126773B 0.000u 0:00.001对于这幅画,结果与预期的一样。

使用这一个,结果会出乎意料地变灰。

下面是一个简单的sscce测试类来显示问题:
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
/* simple test class for convolution matrix */
public class CopyPic {
public static void main(String args[]) throws FileNotFoundException, IOException {
if (args.length < 1) {
System.err.println("Usage: CopyPic <picture_file>");
System.exit(1);
}
String imgPath = args[0];
String inputName = imgPath.substring(0, imgPath.lastIndexOf("."));
File ifile = new File(imgPath);
InputStream fis_in = new FileInputStream(ifile);
BufferedImage bi_in = ImageIO.read(fis_in);
fis_in.close();
int width = bi_in.getWidth();
int height = bi_in.getHeight();
System.out.println(String.format("%s = %d x %d", imgPath, width, height));
int[] rgb_in = new int[width * height];
bi_in.getRGB(0, 0, width, height, rgb_in, 0, width);
BufferedImage bi_out = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// for (int y = 0; y < height; y++) {
// for (int x = 0; x < width; x++) {
// bi_out.setRGB(x, y, rgb_out[y * width + x]);
// }
// }
bi_out.setRGB(0, 0, width, height, rgb_in, 0, width);
display(bi_in, bi_out);
String outputName = inputName + "-copy.png";
File ofile = new File(outputName);
OutputStream fos_out = new FileOutputStream(ofile);
ImageIO.write(bi_out, "PNG", fos_out);
fos_out.flush();
fos_out.close();
System.out.println("Wrote " + outputName);
}
// use that to have internal viewer
private static JFrame frame;
private static JLabel label1, label2;
private static void display(BufferedImage img1, BufferedImage img2) {
if (frame == null) {
frame = new JFrame();
frame.setTitle(String.format("%dx%d Original / Copy", img1.getWidth(), img1.getHeight()));
frame.setSize(img1.getWidth() + img2.getWidth(), img1.getHeight());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
label1 = new JLabel();
label1.setIcon(new ImageIcon(img1));
frame.getContentPane().add(label1, BorderLayout.WEST);
label2 = new JLabel();
label2.setIcon(new ImageIcon(img2));
frame.getContentPane().add(label2, BorderLayout.EAST);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
} else {
label1.setIcon(new ImageIcon(img1));
label2.setIcon(new ImageIcon(img2));
}
}
}发布于 2022-10-11 22:38:36
当ImageIO.read函数创建BufferedImage时,它使用它认为最适合的类型。这种类型可能不是您所期望的。特别是,对于JPG映像,类型可能不是TYPE_INT_ARGB。
这是第二张图像的情况,当您打印该图像的类型时,这种情况就很明显了:
System.out.println(bi_in.getType());对于该图像,它在我的机器上打印10,表示灰灰。
因此,要解决问题,您应该使用:
BufferedImage bi_out = new BufferedImage(width, height, bi_in.getType()); https://stackoverflow.com/questions/74034265
复制相似问题