控制图像缩放算法

时间:2019-01-02 23:16:53

标签: java image javafx java-8

我正在尝试用JavaFX重写Swing图像查看器,但是JavaFX Image构造函数使用的缩放算法质量很低。不幸的是,我不得不依靠调整构造器中图像的大小,因为某些图像太大而无法完全加载到JavaFX的内存中(即使它曾经在Swing中工作)。

这是一个比较。左侧,使用BufferedImage.drawImage缩小图片,并在Graphics.drawImage中使用paintComponent进行渲染(使用抗锯齿渲染提示),而右侧则以相同的缩小分辨率通过JavaFX Image构造函数(将平滑设置为true)。

Comparison

如您所见,JavaFX缩减算法引入了一种锯齿效应。我该如何补救?我认为问题出在图片没有完全加载到内存中,但看来我别无选择。

这是将生成比较的代码。以下面的picture为例。

public static BufferedImage scale(BufferedImage img, int width, int height) {
  int imageType = (img.getTransparency() == Transparency.OPAQUE)
        ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
  BufferedImage scaled = new BufferedImage(width, height, imageType);
  Graphics2D context = scaled.createGraphics();
  context.setRenderingHint(
        RenderingHints.KEY_INTERPOLATION, 
        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
  context.drawImage(img, 0, 0, width, height, null);
  context.dispose();
  return scaled;
}

@Override
public void start(Stage stage) {
  // Load full image in memory, downscale using BufferedImage
  Image image1 = new Image("file:4000x3600.jpg");
  BufferedImage bimg = SwingFXUtils.fromFXImage(image1, null);
  bimg = scale(bimg, 600, 600);
  image1 = SwingFXUtils.toFXImage(bimg, null);

  // Downscale in the Image constructor, saves memory
  Image image2 = new Image("file:4000x3600.jpg", 600, 600, false, true);

  AnchorPane root = new AnchorPane();
  ImageView view1 = new ImageView(image1);
  view1.setLayoutX(0.0);
  view1.setLayoutY(0.0);

  ImageView view2 = new ImageView(image2);
  view2.setLayoutX(600.0);
  view2.setLayoutY(0.0);

  root.getChildren().add(view1);
  root.getChildren().add(view2);
  Scene scene = new Scene(root, 1200, 600);
  stage.setScene(scene);
  stage.show();
}

0 个答案:

没有答案
相关问题