java TrayIcon使用具有透明背景的图像
Posted
技术标签:
【中文标题】java TrayIcon使用具有透明背景的图像【英文标题】:java TrayIcon using image with transparent background 【发布时间】:2010-09-24 18:56:24 【问题描述】:我正在使用以下代码在 Windows 和 Linux 中设置托盘图标。它在 Windows 中运行良好,在 Linux 中运行良好。在 Linux(Ubuntu)中,我将面板设置为(有点)透明,当我添加 GIF(具有透明背景)时,图标的背景显示为灰色和丑陋(参见图像,绿色菱形“!”)。 ...关于如何使我添加的 GIF 图像“保持”其透明背景的任何想法?
alt text http://unarm.org/***/panel_task.jpg
还有我正在使用的图片,如果你想测试的话:
alt text http://unarm.org/***/green_info.gif
import java.awt.*;
import java.awt.event.*;
public class TrayFun
static class ShowMessageListener implements ActionListener
TrayIcon trayIcon;
String title;
String message;
TrayIcon.MessageType messageType;
ShowMessageListener(
TrayIcon trayIcon,
String title,
String message,
TrayIcon.MessageType messageType)
this.trayIcon = trayIcon;
this.title = title;
this.message = message;
this.messageType = messageType;
public void actionPerformed(ActionEvent e)
trayIcon.displayMessage(title, message, messageType);
public static void main(String args[])
Runnable runner = new Runnable()
public void run()
if (SystemTray.isSupported())
final SystemTray tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("green_info.png");
PopupMenu popup = new PopupMenu();
final TrayIcon trayIcon = new TrayIcon(image, "The Tip Text", popup);
trayIcon.setImageAutoSize(true);
MenuItem item = new MenuItem("Close");
item.addActionListener(new ActionListener()
public void actionPerformed(ActionEvent e)
tray.remove(trayIcon);
);
popup.add(item);
try
tray.add(trayIcon);
catch (AWTException e)
System.err.println("Can't add to tray");
else
System.err.println("Tray unavailable");
;
EventQueue.invokeLater(runner);
【问题讨论】:
我猜你必须切换到一个方形图标 :( :( 很高兴你发现 SystemTray 是你的守护程序应用程序的一个很好的替代品。这个新应用程序是关于什么的?: ) 这是秘密吗? 问题,这个图标图像在其他地方显示时是否看起来不透明?例如网页? 这是一个秘密,但我计划很快将它作为一个开源项目发布在这里。图像在其他任何地方显示时看起来都很好。你可以看到我已经嵌入了我的任务栏图像下方和代码上方。 【参考方案1】:问题出在 sun.awt.X11.XTrayIconPeer.IconCanvas.paint() 方法上!
在绘画之前,通过简单地绘制一个 IconCanvas 的背景颜色矩形来业余清除图标背景,以允许图像动画。
public void paint(Graphics g)
if (g != null && curW > 0 && curH > 0)
BufferedImage bufImage = new BufferedImage(curW, curH, BufferedImage.TYPE_INT_ARGB);
Graphics2D gr = bufImage.createGraphics();
if (gr != null)
try
gr.setColor(getBackground());
gr.fillRect(0, 0, curW, curH);
gr.drawImage(image, 0, 0, curW, curH, observer);
gr.dispose();
g.drawImage(bufImage, 0, 0, curW, curH, null);
finally
gr.dispose();
见:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
【讨论】:
【参考方案2】:对于那些寻找“真正”解决方案的人,我开发了一个小型库,它能够显示托盘图标以尊重透明度,并且还接受 SVG 图标(适用于所有平台):
http://skype2gmail.blogspot.com/2011/05/java-tray-icon-transparency.html
它是一个开源库,源代码可以在这里找到:
https://github.com/taksan/native-tray-adapter
该库通过在 linux 下运行时提供 JNI 替代方案(使用 GTK)来解决该问题。
【讨论】:
我注意到这个 GitHub 存储库自 2011 年以来没有大量活动。这仍然是一个可行的解决方案吗?我在这里记录了一些其他平台托盘问题:***.com/a/35919788/3196753。如果有一个可靠、跨平台的解决方案就好了。 在某些语言生态系统(如 Erlang、Haskell 和 Clojure 世界)中,缺乏活动和开放问题意味着它从一开始就没有被破坏。我寻找问题数量不断减少的库,最好是零。【参考方案3】:不是这样的。 . .这很高兴,因为它使用默认的 GNOME 主题来呈现透明度 - 它与它自身的图像无关 - 这是 adobe air / gnome 冲突 - 如果您切换到 gnome 主题,那么默认背景是灰色的它将是灰色而不是白色。它使用系统默认图像,因此即使它已设置,但面板的主题具有 BG 图像以使其看起来像 vista 一样有光泽,例如,它不会这样做。 Adobe Air / Java 不知道您使用透明主题默认设置,因此它使用系统默认设置
【讨论】:
我只是测试了这个“理论”,确实是真的【参考方案4】:JDIC 有一个托盘图标,它们可能支持 linux 中的透明度... https://jdic.dev.java.net/
【讨论】:
【参考方案5】:这个问题可能无法解决。这取决于 Java 在 Linux 中创建托盘子窗口方面是否做得很好。如果 Jave 做错了,在绘制图像时透明度已经丢失。
您使用的图标的真实背景值是多少?是上面显示的灰色调吗?设置为紫色看看是否使用了图片的透明度(Java默认为灰色背景)。
确保您尝试了 PNG 的两种透明度选项:透明颜色索引和 Alpha 通道。 Alpha 通道在 Linux 中很常见,而在 Windows 世界中则不然。
您的图标分辨率太小。在 64x64 或更好的 128x128 中进行。 AFAIK 托盘图标没有标准分辨率,即使是这样,它也肯定不是 16x16。
您可以尝试的另一种格式是 SVG。只有在确保图像的透明度是问题后才可以尝试(参见 1)。
有关此问题的背景信息,请参见此处: http://www.rasterman.com/index.php?page=News(向下滚动至 2006 年 2 月 2 日)
【讨论】:
谢谢。 1)它是透明的(方格背景)...我尝试将其设为紫色,但它在托盘中显示为紫色。 2)我在 GIMP 中保存时尝试了所有不同的 PNG 选项,它们都有相同的结果 3)我还尝试了不同大小的图标 w/相同的结果 4)我尝试了 SVG...显示全部为灰色。 抱歉,空间不足。感谢您的想法。你碰巧有其他想法吗? 所以如果 Java 不能真正理解图像的透明度,那真的很奇怪。也许尝试在应用程序中绘制图像。或者这些图像可能有特定的选项。我不知道还能做什么(也许除了 SystemTray 之外还有其他可用的 API?)【参考方案6】:您是否尝试过将其转换为 .PNG(具有透明度)?我发现 Java 对它们的支持往往更好(根据我的经验)
【讨论】:
以上是关于java TrayIcon使用具有透明背景的图像的主要内容,如果未能解决你的问题,请参考以下文章
Python用PIL将PNG图像合成gif时如果背景为透明时图像出现重影的解决办法
Java Graphics2D - 绘制具有渐变不透明度的图像