首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BufferedImage -> int[] -> BufferedImage导致灰黑色

BufferedImage -> int[] -> BufferedImage导致灰黑色
EN

Stack Overflow用户
提问于 2022-10-11 21:22:44
回答 1查看 64关注 0票数 2

我正在做一些基于维基百科关于图像处理中的内核的页面的卷积矩阵图像滤波的基本实验。

为了计算RGB转换,我正在通过BufferedImage读取位图,然后用getRgb()获取像素。在测试最简单的标识过滤器时,我注意到对于特定的图片,我得到的是一些灰色而不是原始的黑色,而对于其他一些图片,黑色是可以的。

经过更多的测试后,我发现在没有任何转换的情况下,一个简单的BufferedImage -> int[] -> BufferedImage就会导致灰色结果。

我错过了什么?ImageMagick identify显示,两者都是没有alpha通道的8位256色图片.

代码语言:javascript
复制
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测试类来显示问题:

代码语言:javascript
复制
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));
        }
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-11 22:38:36

ImageIO.read函数创建BufferedImage时,它使用它认为最适合的类型。这种类型可能不是您所期望的。特别是,对于JPG映像,类型可能不是TYPE_INT_ARGB

这是第二张图像的情况,当您打印该图像的类型时,这种情况就很明显了:

代码语言:javascript
复制
System.out.println(bi_in.getType());

对于该图像,它在我的机器上打印10,表示灰灰

因此,要解决问题,您应该使用:

代码语言:javascript
复制
BufferedImage bi_out = new BufferedImage(width, height, bi_in.getType()); 
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74034265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档