1

I have searched and googled a lot but can't find a simple solution to this. I want to resize the image according to its actual size and preserving the image ratio at the same time. As you can see from the following sample code, with the preserveRatio property set to true, I am able to resize the image. However, as I resize pass the actual width or height of the image, a white space will appear. How can I resize it without the appearance of the white space?

package test;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


public class Test extends Application {
   private ImageView imageView = new ImageView();
   @Override
   public void start(Stage primaryStage) {

      imageView.setImage(new        Image("https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/800px-Siberischer_tiger_de_edit02.jpg"));
      imageView.preserveRatioProperty().set(true);

      StackPane root = new StackPane();
      root.getChildren().add(imageView);

      imageView.fitHeightProperty().bind(root.heightProperty());
      imageView.fitWidthProperty().bind(root.widthProperty());

      Scene scene = new Scene(root, 300, 250);

      primaryStage.setTitle("Test Image Resizing");
      primaryStage.setScene(scene);
      primaryStage.show();
  }

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
      launch(args);
    }

}
lospejos
  • 1,976
  • 3
  • 19
  • 35
Tania
  • 125
  • 8
  • I do not know how this method `preserveRatioProperty()` works exactly but I believe that to avoid the image stretching and losing its quality, it keeps it with its original size, I do not think it's easy to do what you want but I do not say it's impossible. – Bo Halim Jan 15 '17 at 08:37
  • 1
    What would you like to happen instead of these white stripes? If you want the image to keep its ratio, but the window doesn't have the same ratio as the image, you need to display something around the image. If you want the image to fill the window, and the window doesn't have the same ratio as the image, then the ratio of the image won't be preserved. – JB Nizet Jan 15 '17 at 08:41
  • See also the ensenble/fireworks example cited [here](http://stackoverflow.com/a/31761362/230513). – trashgod Jan 15 '17 at 10:27

1 Answers1

0

You also need to adjust the viewport to make it's dimentions have the correct ratio to fill the whole area with a ImageView:

@Override
public void start(Stage primaryStage) {
    imageView.setImage(new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/800px-Siberischer_tiger_de_edit02.jpg"));
    imageView.setPreserveRatio(true);

    StackPane root = new StackPane();
    root.getChildren().add(imageView);
    root.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> {
        double w = newValue.getWidth();
        double h = newValue.getHeight();
        imageView.setFitWidth(w);
        imageView.setFitHeight(h);
        double ratio = h / w;
        Image image = imageView.getImage();
        double ih = image.getHeight();
        double iw = image.getWidth();
        double vR = ih / iw;
        imageView.setViewport((ratio < vR) ? new Rectangle2D(0, 0, iw, iw * ratio) : new Rectangle2D(0, 0, ih / ratio, ih));
    });

    Scene scene = new Scene(root, 300, 250);

    primaryStage.setTitle("Test Image Resizing");
    primaryStage.setScene(scene);
    primaryStage.show();
}

In this case you can achieve the same effect by using the image as background image for root:

@Override
public void start(Stage primaryStage) {
    StackPane root = new StackPane();
    root.setBackground(new Background(
            new BackgroundImage(new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/800px-Siberischer_tiger_de_edit02.jpg"),
                    BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, new BackgroundSize(0, 0, false, false, false, true)
            )));

    Scene scene = new Scene(root, 300, 250);

    primaryStage.setTitle("Test Image Resizing");
    primaryStage.setScene(scene);
    primaryStage.show();
}
fabian
  • 80,457
  • 12
  • 86
  • 114
  • Fabian, thank you so much for your help. As I have mentioned, I am new to JavaFX and therefore still learning how to "walk". Hopefully, the baby steps that I am taking will soon be turned into "running". Anyway, the examples you have provided have given me much-needed insights. Thank you:) – Tania Jan 16 '17 at 18:58