在java中将图案应用于图像

Sup*_*tar 23 java icons image jradiobutton jcheckbox

我正在尝试为我的程序创建几个类似的视觉样式,每个样式都有不同的颜色主题.为此,我已经实现了使用图标来表示JCheckBoxs和JRadioButtons 的不同状态.而不是为每种可能的颜色制作一套完整的图标,有没有什么方法可以在显示之前拍摄一组并更改图像的色调/饱和度/亮度/ alpha?

Ber*_*sch 13

有一种方法,但你必须使用一些BufferedImage转换.创建它们后,将它们缓存或保存,以便以后轻松重复使用.基本上,您希望从黑色图像(源颜色#000000)开始,该图像仅使用alpha图层来关闭像素(还提供平滑的抗锯齿).例如,在源图像中,每个像素都是黑色,但alpha通道因像素而异.

首先,阅读本文以获取一些背景信息:http://www.javalobby.org/articles/ultimate-image/

完成该入门后,需要将图像加载到BufferedImage:

BufferedImage loadImg = ImageUtil.loadImage("C:/Images/myimg.png");
Run Code Online (Sandbox Code Playgroud)

接下来,您需要创建一个新的BufferedImage以进行转换:

public BufferedImage colorImage(BufferedImage loadImg, int red, int green, int blue) {
    BufferedImage img = new BufferedImage(loadImg.getWidth(), loadImg.getHeight(),
        BufferedImage.TRANSLUCENT);
    Graphics2D graphics = img.createGraphics(); 
    Color newColor = new Color(red, green, blue, 0 /* alpha needs to be zero */);
    graphics.setXORMode(newColor);
    graphics.drawImage(loadImg, null, 0, 0);
    graphics.dispose();
    return img;
}
Run Code Online (Sandbox Code Playgroud)

从本质上讲,setXORMode会将您提供的颜色与源图像中的颜色进行异或.如果源图像是黑色的,那么您指定的任何颜色都将在您指定时写入.使用"0"作为Alpha通道的新颜色时,将遵循原始Alpha通道值.最终结果是您正在寻找的复合材料.

编辑:

您可以使用以下两种方式之一加载初始BufferedImage.最简单的方法是使用Java的新版ImageIO API:http://download.oracle.com/javase/6/docs/api/javax/imageio/ImageIO.html将文件直接加载到BufferedImage.电话会看起来像这样:

BufferedImage img = ImageIO.read(url); 
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用ToolKit创建一个读取图像的方法.

public BufferedImage loadImage(String url) {
    ImageIcon icon = new ImageIcon(url);
    Image image = icon.getImage();

    // Create empty BufferedImage, sized to Image
    BufferedImage buffImage = 
      new BufferedImage(
        image.getWidth(null), 
        image.getHeight(null), 
        BufferedImage.TYPE_INT_ARGB);

    // Draw Image into BufferedImage
    Graphics g = buffImage.getGraphics();
    g.drawImage(image, 0, 0, null);
    return buffImage;
}
Run Code Online (Sandbox Code Playgroud)

当然,如果你注意,我们必须做同样的事情,将图像读入缓冲图像,就像我们做的那样.简而言之,如果您更改colorImage方法的签名以接受Image对象,则只需对getWidth()和getHeight()方法进行一些更改即可使其工作.


Ole*_*lov 5

要计算每个颜色分量的平均值并保持原始 alpha:

public static void tint(BufferedImage image, Color color) {
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            Color pixelColor = new Color(image.getRGB(x, y), true);
            int r = (pixelColor.getRed() + color.getRed()) / 2;
            int g = (pixelColor.getGreen() + color.getGreen()) / 2;
            int b = (pixelColor.getBlue() + color.getBlue()) / 2;
            int a = pixelColor.getAlpha();
            int rgba = (a << 24) | (r << 16) | (g << 8) | b;
            image.setRGB(x, y, rgba);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这最适合我的情况。