Java如何加载本地NSImages?

7
我一直在阅读OS X Java开发工具,以帮助使我的应用程序更符合操作系统的“本地化”。在这个特定的章节中,我发现了一些有趣的内容(重点是我的)。
要将来自应用程序包资源文件夹中的分辨率无关的 tiff、icns 或 pdf 文件加载到您的Java应用程序中,请使用java.awt.ToolkitgetImage()方法。您传递到getImage()的字符串形式为"NSImage://MyImage"。不要包含图像的文件扩展名。还要注意,当用户界面比例因子没有值为1.0时,Sun 2D 渲染器会被禁用。请使用Quartz渲染器,以使图像平滑缩放。
熟悉javax.imageio后,这让我完全惊讶,因为我不知道有其他加载其他文件类型的图像的方法。特别是在过时的平台上,绝对没有支持.tiff等文件。例如,在我的电脑上进行快速测试会得到如下结果:
Supported read formats: [jpg, bmp, gif, png, wbmp, jpeg]
Supported write formats: [jpg, bmp, gif, png, wbmp, jpeg]
'JPEG' reader: com.sun.imageio.plugins.jpeg.JPEGImageReader@5e9f23b4
'JPEG' reader: com.sun.imageio.plugins.jpeg.JPEGImageWriter@378fd1ac

我尝试加载一个简单的.tiff图像并测试了一下:

static Image n;

public static void main(String[] args) {
    JFrame f = new JFrame();
    JPanel p = new JPanel() {
        @Override
        public void paintComponent(Graphics graphics) {
            graphics.drawImage(n, 0, 0, null);
        }
    }
    f.add(p);
    n = Toolkit.getDefaultToolkit().getImage(("/Users/zinedine/Desktop/test_image.tiff");
    f.setVisible(true)
}

没有任何结果:

enter image description here

我又试了一遍:这次,将图像添加到java项目的基本文件夹中,并将其键入为字符串:"NSImage://test_image.tiff"。像我做的每件事情一样,它不起作用。

然而,如果我将花哨的路径字符串更改为NSImage类型的字符串,例如"NSImage://NSApplicationIcon"……

enter image description here

它可以工作。我快速搜索了一下NSImage,找到了一个。看起来这些图像的文件类型是.png。这有点令人不安,因为我期望能得到一个适当的图像。请注意,我也有这样的期望:如果它期望以"NSImage://something"的形式接收参数,那么它可能会忽略其他任何内容。

显然,我有几个问题:

  • How does the Toolkit load the image? If I try to load a .tiff image from my desktop, this is what I get if I call .toString():

    sun.awt.image.ToolkitImage@25f38edc // Also can't be cast to java.awt.BufferedImage
    
  • Are the readers (and writers if any) part of a public API? In other words, can I call something to load my .tiff file into an Image (which I can then cast into a `BufferedImage?

  • And then again, if the readers/writers are part of the API, why doesn't the javax.imageio package locate them?

这看起来可能有些复杂(是的,我很抱歉让你在这个问题上有些困扰),但对我而言,这似乎是预期的,但同时也是错误的行为。额外加分:是否有任何友好(即开源)的图像API(不是JAI)可以处理.tiff文件(和其他文件)?

1个回答

1
您在这里提出了多个问题,但我会尽力进行全部解释。:-)
使用Toolkit加载图像(java.awt.Image和相关类)是“旧”的异步生产者/消费者成像API的一部分,并且可能感觉有些笨拙。它完全适用于加载打包的图标等,但对于加载大型用户提供的图像来说则不太合适,因为您没有进度跟踪,如果有任何错误反馈也很少等等。
这些图像也比BufferedImage不那么有用,如果您想执行任何类型的图像操作。您无法将它们转换为BufferedImage,但可以通过将它们绘制到BufferedImage上来“转换”它们。
Toolkit类是抽象的,并且您使用Toolkit.getToolkit()获取一个具体的实例。这个具体的实例是特定于平台的,并最终使用系统特定的本地调用来进行大多数方法,例如加载图像。
苹果的Java实现确实具有一些额外功能,例如允许您使用特殊的URI方案加载苹果系统映像。似乎它也可以通过使用“@2x”命名约定来加载捆绑的图像,甚至可以在OS X中加载多尺度TIFF或可缩放PDF,用于应用程序的分辨率独立图形。
请注意,要使此功能起作用,您需要将应用程序打包为应用程序包,并将图像放置在包的Resources文件夹中(即Contents/Resources)。并且你必须使用base name引用图像,不带扩展名。据我所知,您无法使用此功能读取未与应用程序捆绑的随机TIFF文件(即用户提供的内容)。
此外,这个功能是特定于苹果JRE的,并且只能在苹果自己的JRE和OS X上工作。它不是公共Java API的一部分,也无法跨平台运行。我建议您节俭地使用该功能,并仅在OS X上实现更好的系统集成(即使您的应用程序看起来更本地)。
要读取(和写入)任何TIFF(或其他格式),您应该使用ImageIO和一些适当的插件。由于某种原因,JRE不带有TIFF格式的插件,但存在几个第三方插件。
如果您不想使用JAI(通过jai_imageio.jar),我可以推荐我的TwelveMonkeys库,它支持TIFF以及相当多的其他格式。它使用业务友好的开源BSD许可证。
还有Apache Commons ImagingiCafe和可能其他一些可以读/写TIFF的库,但这些都有自己的自定义API,使它们在我看来不够灵活且更具专有性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接