7

我正在开发一个必须具有自定义图标的应用程序。提供的图标在所有尺寸(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 的方法(即使以一种骇人听闻的方式)还是我必须使用其他图像格式?

更新

我将我的 .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 从未显示在应用程序的左上角(尽管这是最接近的尺寸)。

4

3 回答 3

7

功能要求

请参阅相关功能请求:

该功能目前未分配给某个版本,但您可以根据需要对其进行投票或评论。

使用第三方库加载 ico 文件

同时,您可以使用各种实用程序来创建java.awt.image.BufferedImage格式图标,然后使用SwingFXUtils. haraldK 在他的回答中提供了这种方法的示例。另一个例子是柳树浏览器的收藏图标获取器,它使用了image4j库,虽然 haraldK 的十二只猴子库可能是更好用的库。您的另一种选择是将基于 awt 的图标库之一的源代码移植到 JavaFX,使用WritableImage.

建议

您不使用 png 因为它始终显示 16x16 的理由对我来说有点奇怪,因为stage.getIcons()文档返回了您可以添加到的图像列表(您不仅限于添加单个图标)。从javadoc:

获取要在窗口装饰和最小化时使用的图标图像。图像应该是同一图像的不同尺寸,并且将选择最佳尺寸,例如。16x16, 32,32。

附加问题

如果根据大小,图像并不总是相同怎么办?

提供不同的图像可能没问题。如果系统插入提供的图像以创建未提供大小的图标,这可能会导致问题 - 但我认为系统不太可能这样做。“图像应该是同一图像的不同尺寸”更多的是指导而不是实际规则。如果您需要不同尺寸的不同图像,请尝试为此提供多个 png 图像,看看会发生什么。

于 2015-02-12T12:02:13.977 回答
5

我不认为 JavaFX 直接支持 ICO 格式。我很确定该列表仅是 JPEG、GIF 和 PNG,但我还没有找到证实这一点的官方来源。

但是,您可以使用我的 ImageIO ICO 插件来读取 ICO 文件,并Image使用SwingFXUtils.toFXImage(bufferedImage, null).

请注意,阅读器只是按照图标在 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);
于 2015-02-12T10:26:31.233 回答
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);
于 2015-06-11T07:33:43.603 回答