JavaFX 2.2对.ico的图像支持?

时间:2015-02-12 10:16:30

标签: image javafx-2 ico

我正在开发一个必须有自定义图标的应用程序。所提供的图标在所有尺寸(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从未显示在应用程序的左上角(尽管这是最接近的尺寸)。

3 个答案:

答案 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);