【问题标题】:Want a JLabel with an image that has a transparent background想要一个带有透明背景图像的 JLabel
【发布时间】:2014-02-09 15:15:30
【问题描述】:

我在 JTable 的自定义渲染器中将此图标用于 JLabel。选择表格中的行时,图标背景显示为白色。

我使用paint.net 创建了一个绿色三角形,并将其背景设置为白色,alpha 为255。这就是我在这段代码中用来为JLabel 创建IconImage 的图像;出于外部原因,我对图标使用不同的宽度。这是一个示例程序,展示了所做的工作:

package spacecheck.images;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * represents an icon used in the directory tree; handles 'expanded' and
 * 'unexpanded' directories as well as indentation representing different
 * levels.
 * @author rcook
 *
 */
public class TreeIconExample
{
  public static int UNEXPANDED = 1;
  public static int EXPANDED = 2;

  @SuppressWarnings({"unused"})
  private void say (String msg) { System.out.println(msg); }

  private static ImageIcon expandedIcon = null;
  private static ImageIcon unexpandedIcon = null;
  private static int       iconHeight = 0;
  private static int       iconWidth  = 0;

  private static ArrayList<ImageIcon> cachedExpandedIcons = new ArrayList<ImageIcon>();
  private static ArrayList<ImageIcon> cachedUnexpandedIcons = new ArrayList<ImageIcon>();

  static
  {
    expandedIcon = new ImageIcon(TreeIconExample.class.getResource("images/Expanded.GIF"));
    unexpandedIcon = new ImageIcon(TreeIconExample.class.getResource("images/Unexpanded.GIF"));
    iconHeight = unexpandedIcon.getIconHeight();
    iconWidth =  unexpandedIcon.getIconWidth();
  }

  public TreeIconExample()  {  }

  public static void main(String ... arguments)
  {
    JFrame frame = new JFrame("icon test");
    frame.setBackground(Color.blue);
    JLabel label = new JLabel("background test");
    label.setBackground(Color.magenta);
    TreeIconExample treeIcon = new TreeIconExample();
    ImageIcon icon = treeIcon.getIcon(2, false);
    label.setIcon(icon);
    frame.add(label);
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * return the icon for an expanded or unexpanded level
   * @param int level of folder relative to other levels displayed;
   * starts at 0 and increases with depth
   * @param boolean indicates whether this level is expanded or not.
   * @return ImageIcon appropriate for expansion flag and level.
   */
  public ImageIcon getIcon(int level, boolean expanded)
  {
    ImageIcon result = null;

    // generate this icon and store it in the cache before returning it.
    ImageIcon baseIcon = unexpandedIcon;
    if (expanded) { baseIcon = expandedIcon; }
    int iconH = iconHeight;
    int iconW = iconWidth*(level+1);

    BufferedImage bufferedImage = new BufferedImage(iconW,iconH,BufferedImage.TYPE_INT_ARGB);
    Graphics g = bufferedImage.getGraphics();

    g.fillRect(0, 0, iconW, iconH);
    g.drawImage(baseIcon.getImage(), iconWidth*level, 0, null);
    result = new ImageIcon(bufferedImage);

    return result;
  }
}

这是我的结果:

我想做的是消除图标的白色部分;我希望它是透明的,所以 JLabel 的背景会显示出来。我不知道为什么这个程序中既没有出现洋红色也没有蓝色;如果有人愿意告诉我,我将不胜感激。但图像上的透明背景是我想要弄清楚的主要内容。

【问题讨论】:

    标签: java image swing icons


    【解决方案1】:

    图片的透明背景是主要的

    它不透明的原因是 明确地用不透明的默认颜色填充它:-)

    Graphics g = bufferedImage.getGraphics();
    say("" + g.getColor());
    g.fillRect(0, 0, iconW, iconH);
    

    输出:

    java.awt.Color[r=255,g=255,b=255]
    

    所以要么不填充,要么使用完全/部分透明的颜色。

    我不知道为什么这个程序中既没有品红色也没有蓝色;如果有人愿意告诉我,我将不胜感激

    • (已在之前的帖子中回答)洋红色未显示,因为标签默认为 !opaque:表示其背景未填充其背景颜色
    • 蓝色没有显示,因为你将它设置为被它的 contentPane 覆盖的框架:默认情况下,后者是一个普通的 JPanel,不透明度默认为 true,也就是说,它用它的背景填充它的区域

    要查看蓝色,请将其设置为 contentPane 的背景颜色或更改其不透明度:

    frame.getContentPane().setBackground(Color.blue);
    // or
    frame.setBackground(Color.YELLOW);
    ((JComponent) frame.getContentPane()).setOpaque(false);
    

    【讨论】:

    • 图像有两个白色部分,一个是由“fillRect”调用创建的。删除它后,我仍然在三角形周围留下一个白色区域,我想是因为当我在图形编辑器中创建三角形时,我在三角形周围有一个背景。我用过 mspaint,它没有提供透明颜色;我现在正在使用 gimp,这是应该的,但我不知道该怎么做。我尝试用不透明度为 0% 的白色填充该背景,然后导出为 PNG,但它仍然显示为白色。有些选项不适合评论,需要吗?
    【解决方案2】:

    我认为你应该对缓冲图像的 Graphics2D 使用渲染提示:

    Graphics2D g = bufferedImage.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    

    另外,为什么你有一个fillRect 呢?我猜它不会是透明的。

    编辑:尝试运行代码后,仅删除 fillRect 就足以解决白色矩形问题:

    注意:我使用的图像是在 gimp 中创建的 gif。

    【讨论】:

    • 我会寻找fillRect的替代品。我不能使用你的代码; getGraphics() 返回的是 Graphics,而不是 Graphics2D,Graphics2D 没有 setRenderingHint。
    • 对不起...您需要 createGraphics 来获取 Graphics2d。但是我不确定它是否会起作用,我还没有尝试过。我仍然不明白你为什么要填充矩形。你只是想用 alpha 通道绘制图像,对吧?
    • 我想把图片中的绿色三角形放到标签上,让标签的背景显示在所有未被三角形覆盖的部分。
    • 我试过你的例子。如果删除填充矩形,白色矩形就消失了(因为你没有画它:)
    • 你能在gimp中逐步完成不透明图像的创建吗?我似乎无法弄清楚...
    【解决方案3】:

    将标签设置为不透明

    label.setOpaque(true)。如果它不起作用。使用无背景的 PNG 文件。

    如果还是不行。 您可以尝试不同的方法(例如制作一个覆盖paintComponent 并绘制三角形的自定义标签类)。

    【讨论】:

    • setOpaque(true) 显示洋红色,但我仍然有洋红色顶部三角形的白色背景。我很乐意使用没有背景的 PNG,但我不知道如何创建一个 - 有你使用的任何工具吗?
    • 好吧,你可以搜索谷歌(有没有png的)。还有一个网站蒸发了背景。 clippingmagic.com另外,你可以用photoshop来做。
    【解决方案4】:

    当您使用图形时,我认为您正在寻找的是:

    Graphics g = bufferedImage.getGraphics();
    Graphics2D g2d = (Graphics2D) graphics;
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
    

    您可以选择不透明度级别,在 0 和 1 之间更改值 0.3f

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-24
      • 2019-12-13
      • 2011-08-06
      • 2015-11-12
      • 2019-09-22
      • 1970-01-01
      • 2012-05-26
      • 2012-10-15
      相关资源
      最近更新 更多