我正在开发一个必须有自定义图标的应用程序。所提供的图标在所有尺寸(256x256,48x48,32x32)中都是相同的,除了在16x16中图标被简化。
我想到了.ico格式(我可以存储所有不同的图标并让操作系统显示最佳)但javafx.scene.image似乎不支持它(我没有找到任何格式)关于那个的确认。)
以下是我设置图标的方式
stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon.ico")));
在这种情况下,图标永远不会显示。如果我将此图标转换为.png图像,则可以正常显示相同的图标(即使是16x16)。
在JavaFX 2.2中是否有办法显示.ico(即使是以hacky方式)或者我是否必须使用其他图像格式?
我将.ico分成多个png(每个大小一个),然后逐个加载。
stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon_16x16.png")));
stage.getIcons().add(new Image(getClass().getResourceAsStream("/path/to/icon_256x256.png")));
256x256和16x16是两个不同的图像,但16x16从未显示在应用程序的左上角(尽管这是最接近的尺寸)。
答案 0 :(得分:7)
功能请求
请参阅相关功能请求:
此功能目前尚未分配给版本,但如果您愿意,可以对其进行投票或评论。
使用第三方库加载ico文件
与此同时,您可以使用各种实用程序以java.awt.image.BufferedImage
格式创建图标,然后使用SwingFXUtils
将其转换为JavaFX。 haraldK在他的回答中提供了这种方法的样本。另一个例子是使用fav icon fetcher for the willow browser库的image4j,尽管haraldK的十二个猴子库可能是更好的库。您的另一种选择是将其中一个基于awt的图标库的源代码移植到JavaFX,并使用WritableImage
。
建议
你不使用png因为它总是显示16x16的原因对我来说有点奇怪,因为stage.getIcons()
文档会返回你可以添加的图像列表(你不仅限于添加单个图标)。来自javadoc:
获取要在窗口装饰中使用的图标图像以及最小化时的图像。图像应该是相同图像的不同尺寸,并且将选择最佳尺寸,例如。 16x16,32,32。
其他问题
如果根据尺寸,图像并不总是相同
,该怎么办?
提供不同的图像可能没问题。如果系统插入提供的图像以创建未提供尺寸的图标,则可能会导致问题 - 但我认为系统不太可能这样做。 “图像应该是同一图像的不同大小”更多的是指导而不是实际规则。如果您需要不同尺寸的不同图像,请尝试为此提供多个png图像,并查看会发生什么。
答案 1 :(得分:5)
我认为JavaFX不直接支持ICO格式。我很确定这个列表只有JPEG,GIF和PNG,但我还没有找到证实这一点的官方消息来源。
但是,您可以使用我的ICO plugin for ImageIO阅读ICO文件,并使用SwingFXUtils.toFXImage(bufferedImage, null)
将图片转换为FX Image
。
请注意,阅读器只是按照ICO文件中找到的顺序返回图标,因此ImageIO.read(...)
不会为您提供所需的图标(它只会读取第一个图标)。相反,您需要阅读每个图标,转换并将所有图标添加到您的舞台。 FX将为您选择正确的尺寸。 : - )
类似的东西:
ImageInputStream stream = ImageIO.createImageInputStream(getClass().getResourceAsStream("/path/to/icon.ico"));
ImageReader reader = ImageIO.getImageReaders(stream).next();
reader.setInput(stream);
int count = reader.getNumImages(true);
List<Image> fxImages = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
BufferedImage bufferedImage = reader.read(i, null);
Image fxImage = SwingFXUtils.toFXImage(bufferedImage, null);
fxImages.add(fxImage);
}
stream.close(); // Remember to close/dispose in a finally block
reader.dispose();
// ...
stage.getIcons().addAll(fxImages);
答案 2 :(得分:0)
使用image4j:
ArrayList<Image> lImages = new ArrayList<>();
ICODecoder.read(Global.FILE_ICON).stream().forEach((lBufferedImage) -> lImages.add(SwingFXUtils.toFXImage(lBufferedImage, null)));
this.getStage().getIcons().addAll(lImages);