JavaFX剪贴板扭曲图像。 DPI应该受到指责?

时间:2017-08-18 23:56:18

标签: java scala javafx

当试图显示存储在系统剪贴板中的图像时,我遇到了这个问题:生成的图片总是比原始图片大,而且有点模糊。

这是我使用的(在Scala中):

不,我的代码完全一样,它只是在Scala中(我也试过运行Java版本,结果相同)

import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.image.ImageView
import javafx.scene.input.Clipboard
import javafx.scene.layout.StackPane
import javafx.stage.Stage

object Test extends App{
  Application.launch(classOf[HelloWorld], args: _*)
}

class HelloWorld extends Application {
  override def start(primaryStage: Stage) {
    primaryStage.setTitle("Hello World!")
    val root = new StackPane        
    val image = Clipboard.getSystemClipboard().getImage()
    val imageView = new ImageView(image)
    root.getChildren.add(imageView)
    primaryStage.setScene(new Scene(root, 300, 250))
    primaryStage.show
  }
}

原始图片和ImageView的内容: http://imgur.com/AFJudkL

我还尝试将图片保存到文件中但仍然失真,所以问题不在ImageView中。

甚至有一个疯狂的想法从WinAPI调用SetProcessDPIAware,绝对没有效果。

有没有办法在没有扭曲的情况下显示图像?

谢谢!

更新:我已经提供了完整版本的代码(它与下面的Java版本完全相同。我在Windows 10上运行它,jdk1.8.0_131,DPI是设定为175%。

我越来越确定我遇到的问题是由于DPI - ImageView显示的图像正好是原始图像的1.75倍。现在我可以使用以下技巧强制它的大小合适:

imageView.setFitHeight(image.getHeight/1.75)
imageView.setFitWidth(image.getWidth/1.75)

但它仍然模糊不清。此外,我发现了一篇很棒的博客文章来处理这个问题(不同的方面,但是 - 拍摄快照)。但是,我不知道如何将这个解决方案应用到我的难题中。

http://news.kynosarges.org/2017/02/01/javafx-snapshot-scaling/

1 个答案:

答案 0 :(得分:0)

您应该尝试设置图像视图的preserveRatio属性。

https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/ImageView.html#preserveRatioProperty

更新

我将您的代码片段转换为可执行示例,当我在Mac(Retina)上运行时,我根本看不到任何失真。那么,您的代码(您没有提供的代码)与我的代码有何不同以及Windows框的相关特征是什么?

public class ClipboardBug extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
          primaryStage.setTitle("Hello World!");
          StackPane root = new StackPane();
          Image image = Clipboard.getSystemClipboard().getImage();
          ImageView imageView = new ImageView(image);
          imageView.setPreserveRatio(true);
          root.getChildren().add(imageView);
          primaryStage.setScene(new Scene(root));
          primaryStage.sizeToScene();
          primaryStage.show();
    }

}