Контроль над алгоритмом масштабирования изображения - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь переписать средство просмотра изображений Swing в JavaFX, однако алгоритм масштабирования, используемый конструктором изображений JavaFX, имеет очень низкое качество. К сожалению, мне приходится полагаться на изменение размера изображения в конструкторе, потому что некоторые изображения слишком велики для полной загрузки в память для JavaFX (даже если раньше это работало в Swing).

Вот сравнение. Слева, используя BufferedImage.drawImage, чтобы уменьшить масштаб изображения и отрендерив его с помощью Graphics.drawImage в paintComponent (используя подсказку рендеринга сглаживания), а справа это же изображение, загруженное с тем же уменьшенным разрешением через конструктор JavaFX Image ( установить в 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...