BufferedImage转int[]再转回后部分灰度图变黑灰色的问题排查
灰度图复制时黑色变灰色的问题
我正在基于图像处理核的维基百科内容,进行卷积矩阵图片滤波的基础实验。为计算RGB变换,我通过BufferedImage读取位图,调用getRgb()获取像素数组。测试恒等滤镜时发现,部分图片原本的黑色变成了灰色,另一部分图片则显示正常。进一步测试发现,即使不做任何变换,仅执行BufferedImage -> int[] -> BufferedImage的操作也会出现该灰度异常问题。
使用ImageMagick的identify命令查看图片信息:
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
两张图均为无Alpha通道的8位256色灰度图。其中一张处理后结果正常:
另一张处理后黑色变为灰色:
以下是复现该问题的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)); } } }
内容的提问来源于stack exchange,提问作者Seki
相关产品推荐
相关产品推荐

