首页 > 解决方案 > 控制图像缩放算法

问题描述

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

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

比较

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

这是一个将生成比较的代码。以下为例。

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();
}

标签: javaimagejavafxjava-8

解决方案


推荐阅读