当前位置: 首页 > 知识库问答 >
问题:

如何在JavaFX中正确地从剪贴板获取图像;挣扎和不挣扎的应用程序之间有什么区别?

施凡
2023-03-14

JavaFX从Windows剪贴板获取图像的默认方式,

Clipboard.getSystemClipboard().getImage();

,似乎已损坏。

图像的透明度似乎出了问题。设置在黑色背景上,图像看起来很好,但设置在白色背景上,根本没有显示任何内容。

您可以使用这个最小、完整、可验证的示例测试剪贴板。

环境: Windows 7,Java8更新202

下面,我来描述一下我已经知道的事情。

  • 从剪贴板获取图像 Awt vs FX
  • 剪贴板中的图像在 JavaFX 8 应用程序中未正确显示

然而,没有人抓住问题的核心或得到答案。

我似乎无法在Java Bug数据库中找到有关此问题的错误。

图像的这个问题不会发生在AWT剪贴板上,但我想要一个使用JavaFX剪贴板的解决方案。

我知道Windows剪贴板包含相同内容的多个版本,只是格式不同。使用InsideEclipboard或免费剪贴板查看器可以轻松查看。

JavaFX剪贴板识别某些格式;有时它有不同的名称。application/x-java-rawimage 是 Java 所认为的图像;在代码中,您将此称为DataFormat.IMAGE

我怀疑Windows中的DIB剪贴板格式与Java的应用程序/x-java-rawimage匹配,但在源代码中找不到证明。

JavaFX似乎在将图像复制到剪贴板的各种应用程序中存在同样的透明度问题:

    < li>Adobe Reader(来自带有图像的PDF) < li>Foxit阅读器(来自带有图像的PDF) < li>Microsoft Word 365(来自a 。带有图像的docx文件) < li>Windows 7的画图(< code >)。png,< code >。jpg,< code >。gif,< code >。bmp) < li>Greenshot(这是一个增强的屏幕截图实用程序) < li>Firefox 65.0.2(复制Google.com徽标)

我还发现了一些将图像复制到剪贴板的应用程序,JavaFX可以使用默认方法将它取出来,没问题:

  • 油漆。net
  • PrtScn按钮
  • Windows截图工具
  • Google Chrome 72.0.3626.121(复制Google.com徽标)

一个适当的答案应该是:

  • 简单、具体地解释,并举例说明为什么某些应用程序会出现问题,而其他应用程序不会出现问题,以及
  • 找出JDK实现中出现问题的地方,并具体说明如何为大多数有问题的应用程序修复所述实现,而不破坏已经工作的应用程序。
    • 如果改变JDK的实现不可行,一个适当的答案将提供一个最小、完整和可验证的示例,显示当从Adobe Reader复制图像时,JavaFX代码从JavaFX剪贴板生成<code>图像

    如果你不能帮忙,但认为这是一个经过充分研究的问题,考虑投票,或与朋友分享。

共有1个答案

富涛
2023-03-14

在这两种加载方法中,生成的JavaFx图像都支持透明性,但不应该支持透明性。然而,AWT加载方法使用了一种中间可转移方法,该方法使用不透明的DirectColorModel来创建图像。结果,AWT图像看起来是正确的,尽管底层图像仍然支持透明度。

不幸的是,这个问题源于一个可能无法解决的更深层次的问题,请看:https://bugs.openjdk.java.net/browse/JDK-8041459

当java使用alpha通道保存图像时,它将图像编码为YCbCr加上第4个alpha通道。问题是其他应用程序将4通道jpeg识别为RGB或CMYK图像,这就是为什么我们在图像中有错误的颜色。最好的解决方案是在没有alpha通道的情况下将图像转换为其他颜色类型,然后保存它。它无法修复,jpeg规范没有规定这一点,它说颜色空间取决于应用程序,java决定将alpha通道编码为YCbCrA,就是这样。

与其尝试手动操作图像html" target="_blank">数据,更简单的方法可能是将图像与矩形混合,并使用组而不是ImageView来显示。下面是一个例子:

private void loadImageFromJavaFXClipboard(final Group group) {
    System.out.println("Adding an image from the JavaFX Clipboard...");
    final Clipboard clipboard = Clipboard.getSystemClipboard();

    if (clipboard.hasImage()) {
        final Image image = clipboard.getImage();

        setupImageFixingGroup(group, image);
    } else {
        new Alert(Alert.AlertType.INFORMATION, "No image detected on the Clipboard!").show();
        group.getChildren().clear();
    }
}

private void setupImageFixingGroup(Group group, Image image) {
    final ImageView view = new ImageView(image);
    view.setBlendMode(BlendMode.LIGHTEN);

    final Rectangle blend = new Rectangle(image.getWidth(), image.getHeight(), Color.BLACK);
    blend.widthProperty().bind(image.widthProperty());
    blend.heightProperty().bind(image.heightProperty());

    group.getChildren().clear();
    group.getChildren().addAll(blend, view);
}

这是您的最小、可验证、完整示例的工作版本:https://pastebin.com/rzhzMui5.我用许多图像(包括您的gif中的图像)对其进行了测试,但没有针对您包含的每个案例明确测试它。

 类似资料:
  • 我要制作一个原生(意思是;不在浏览器中)移动应用程序。由于我是一名Web开发人员,我正在努力决定是否应该尝试Phonegap还是只是在java或Objective-c中构建一个原生应用程序。 应用程序要求很简单。GPS/wifi定位、Facebook集成,我想我需要一个数据库来处理一些特定于Facebook应用程序的朋友关系。比如说比赛中的高分,诸如此类的东西。 我是一名web开发人员,目前既不懂

  • 如有任何帮助,将不胜感激。 谢谢-杰克

  • 我正在努力和Chromium正在构建并崩溃我的计算机,因为这是一个持续数天的过程。 但是,我不能把在之后,因为它将不可访问,如果我将它放在之前,则内容字符串将变得过时。 我该如何解决这个问题?

  • 我一直试图通过示例来学习xcode和swift,我已经尝试了我搜索的大量示例,但所有这些示例都以这样或那样的方式失败了...通常是错误的swift版本或语法。我想做一个非常简单的应用程序,对我的个人气象站进行api调用,并将json数据打印到我的single view应用程序上的文本框或框架中。我想学习的细节和介绍,我走。我想完善的故事板和视图,因为我学习新的概念。 https://api.wea

  • 本人双一流牛马毕业生 无手撕,面试官很年轻很仁慈,感觉就像学长,我说不了解也不会为难我,甚至还会帮我缓解压力 因为公司引擎主用unity,我用的UE4,面试官没问太多引擎知识 1面: 0、开局先聊了一下玩过的游戏,大脑就很容易活跃起来 1、挖了一下UE4项目,主要问一些模块的设计,答的还不错 2、烂大街的http服务器项目 准备不充足 2.1、epoll数据结构是怎么样的? --结构体数组?好像还

  • 如果我打开浏览器并复制页面的所有文本和图像(Ctrl+a),然后粘贴到Microsoft Word(例如)中,文本和图像都将被粘贴。 我正在尝试编写Java代码,从剪贴板内容中提取文本和所有图像,以便在程序中使用文本/图像,例如稍后在GUI中显示图像,并提供支持文本。 现在,我的代码成功地从包含文本和图像的剪贴板内容中提取文本,但是图像部分失败了。图像代码仅在剪贴板内容包含单个图像(如按下打印屏幕