如何使JButton ImageIcon中的颜色透明(透明)

3
我正在使用javax.swing制作我的国际象棋游戏。 我使用gridLayout(8,8)填充了JButtons,将背景颜色设置为棕色,并在棋盘上通常使用浅棕色。 现在我想把我从Google图片中获得并在paint.net中编辑的ImageIcon(king,rock等)放在那些按钮上。

white king on gray background

但是大多数棋子可以从灰色按钮移动到浅灰色按钮。 所以我可以让所有棋子都在浅灰色背景上

white king on light gray background

并根据JButton piece落地的位置切换ImageIcon(但我宁愿不这样做), 或者使图像的背景颜色透明,但我不知道如何做到这一点(例如,Swing是否自动使某些颜色透明)。

感谢您的帮助。


2
为什么你不在paint.net中将图像的背景设为透明? - eldo
不幸的是,如果我在paint.net中从一个图像中删除背景(只保留图像本身,其余部分都是黑白方块),然后将其作为ImageIcon加载到按钮上,它将具有白色背景而不是透明。 - Fredegar
2
@eldo已经概述了最佳方法。在专门的绘画应用程序中将纯色BG更改为透明。 "是否有一些颜色可以自动变成透明" 不是的。另请参见创建一个健壮,可调整大小的Swing Chess GUI,以获取象棋图标的不同方法(在运行时生成它们)。 - Andrew Thompson
@Fredegar 你确定你的背景是透明的吗?难道不是白色背景层或其他什么东西吗? - eldo
@eldo 是的,我在那些图片上使用了透明背景,但是我将它们保存为 .jpg 格式。然后我看到了 Ansharja 的回答并且看到了他/她的黑色车和白色皇后的例子,意识到他/她的图片是以 .png 格式保存的,所以我把我的图片也改成了 .png 格式,这样就没有白色背景了。非常感谢大家的帮助,我的问题已经解决了。 - Fredegar
@Fredegar 哦,是的,jpg没有透明度。 - eldo
1个回答

2
您应该看一下 RGBA 颜色模型
在这个模型中,A 代表 alpha 通道,通常用作不透明度通道。
这意味着您可以通过将颜色的 alpha 值设置为 0 来获得“透明”颜色。 java.awt.Color 类提供了一些构造函数,您可以在其中指定颜色的 alpha 值,例如:
Color(int r, int g, int b, int a) 创建一个 sRGB 颜色,其红色、绿色、蓝色和 alpha 值在范围 (0-255) 内。
如果您找不到可以给您提供此选项的程序,您可以自己使图像的背景颜色透明。
例如,我编写的这段代码尝试从您的“白色国王在灰色背景上”的图像中删除背景颜色。如果您尝试编译和运行,您应该会得到这个结果:

Test screenshot

如您所见,您的图像并没有完全去除背景,这是因为背景由不同颜色组成。
但是,这个例子向您展示了您可以操作图像像素以获得透明度。
我认为最好的选择是在网上搜索一些已经具有透明背景的棋盘图片。
例如,我可以在这里发布一些链接(我不知道是否存在版权问题,请注意),如果您检查URL,您可以轻松获取所有图片: 黑色车 白色皇后 示例代码:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class TransparentTest
{
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    BufferedImage image = ImageIO.read(new File("KING.jpg"));
                    BufferedImage transparentImage = removeColors(image,new Color(245,222,180));
                    createAndShowGUI(image,transparentImage);
                }
                catch(IOException ex) {
                    JOptionPane.showMessageDialog(null,"Please check your file image path","Error",JOptionPane.ERROR_MESSAGE);
                }
            }
        });
    }
    public static void createAndShowGUI(BufferedImage image,BufferedImage transparentImage) {
        JPanel pane = new JPanel(new FlowLayout(FlowLayout.CENTER,40,10));
        pane.setBackground(Color.BLUE);
        pane.add(new JLabel(new ImageIcon(image)));
        pane.add(new JLabel(new ImageIcon(transparentImage)));
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    public static BufferedImage removeColors(BufferedImage image,Color... colorsBlackList) throws IOException {
        int height = image.getHeight(), width=image.getWidth();
        BufferedImage transparentImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB); 
        for(int y=0;y<height;y++) {
            for(int x=0;x<width;x++) {
                int pixel = image.getRGB(x,y);
                int red = (pixel>>16) &0xff;
                int green = (pixel>>8) &0xff;
                int blue = (pixel>>0) &0xff;
                int alpha = 255;
                // Settings opacity to 0 ("transparent color") if the pixel color is equal to a color taken from the "blacklist"
                for(Color color : colorsBlackList) {
                    if(color.getRGB() == pixel) alpha = 0;
                }
                transparentImage.setRGB(x,y,(alpha&0x0ff)<<24 | red<<16 | green<<8 | blue);
            }
        }
        return transparentImage;
    }
}

谢谢,这非常有帮助。 - Fredegar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接