ImageIO.read(png)失去透明度

时间:2018-07-22 21:24:53

标签: java javax.imageio

使用(1)时我已经测试过我的图像,而它是透明图像时类型为TYPE_3BYTE_BGR,使用(2)时我的图像显示为透明,有人可以向我解释我做错的地方吗?< / p>

这是我的代码:

public static void main(String[] args){

    Frame frame = new Frame();
    frame.setSize(200, 200);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);
    frame.getContentPane().setBackground(Color.PINK);
    BufferedImage image;
    try{
        image = ImageIO.read(new File("my_path"));
    }catch(IOException e){
        image = null;
    }
    JLabel label = new JLabel(new ImageIcon("my_path"));
    //JLabel label = new JLabel(new ImageIcon(image));
    frame.getContentPane().add(label);
    label.setBounds(10, 10, 6, 10);
    frame.setVisible(true);

}

Here是我的形象。

谢谢!

PS:Btw网站必须损坏,我无法粘贴我的代码,不得不重写它,很奇怪。

PS2:这也是我第二次打招呼!当第一行被删除...

1 个答案:

答案 0 :(得分:0)

您的图像文件是一个24位RGB PNG文件,带有一个可选的tRNS块,指定了一种应被视为透明的RGB颜色(与具有完整alpha通道的32位RGBA PNG相对)。

由于某种原因,JRE随附的标准PNGImageReader不会为tRNS块的RGB PNG创建透明图像。根据规范,可选块(以小写字母开头)可以被解码器忽略,因此这是完全可以接受的行为。

但是,您可以使用ImageIO API读取PNG的元数据,如果有一个tRNS块,则可以创建一个透明的BufferedImage并自己应用该透明度(替换所有RGB值)等于tRNS块中的RGB值)。但是,如果您只想阅读与应用程序捆绑在一起的图标,则这是很多额外的工作。

最简单的解决方法是只存储具有调色板和透明度的PNG或完整的32位RGBA PNG,这两个ImageIO都支持它们,而无需进行任何其他工作。

它使用“直接” ImageIcon方法工作的原因是,ImageIcon使用了与ImageIO完全不同的PNG解码器,后者似乎确实应用了tRNS块(在您的情况,但我认为没有必要,因此行为可能因JRE或平台而异,您必须进行测试)。