Javafx как обрезать изображение один раз для нескольких соотношений сторон

Я создаю настольное приложение на JavaFX, которое позволяет пользователю искать людей в разных категориях. Существует экран, на котором каждая категория отображается в виде плитки с изображением (соотношение сторон 1: 1). Когда вы щелкаете плитку, открывается другая страница, и изображение с плитки теперь должно отображаться в качестве фонового изображения (соотношение сторон 16: 9). Изображения выбираются администратором, поэтому их необходимо обрезать, потому что они могут быть слишком большими, иметь неправильное соотношение сторон и т. д.

Интересно, как настроить простой способ позволить пользователю с правами администратора выбрать желаемое изображение без необходимости дважды обрезать изображение (один раз как 1: 1 и один раз как 16: 9). Я думал об кадрировании только до 1: 1, а затем для отображения как 16: 9, просто увеличивая изображение, но это приводит к плохому качеству, если разрешение недостаточно высокое.

Для кадрирования я ссылаюсь на этот пост от Роланда: Как сделать приложение Javafx Image Crop

Кажется, вы могли бы использовать два изображения. Один для плитки, а другой для фона. Фоновый вы можете отредактировать с помощью какой-нибудь программы для редактирования фотографий.

Sedrick 10.09.2018 15:52
0
1
139
1

Ответы 1

Для фоновых изображений вы можете просто указать, что изображение должно закрывать Region.

ImageView позволяет указать viewport, позволяя указать область Image, которая должна отображаться. Если выбран соответствующий вариант, обрезка будет сделана за вас.

В следующем коде для простоты используется одно и то же соотношение:

@Override
public void start(Stage primaryStage) {
    final Image image = new Image(URL);

    // size to use for both nodes
    double targetHeight = 400;
    double targetWidth = targetHeight * 16 / 9;

    ImageView imageView = new ImageView(image);
    imageView.setFitWidth(targetWidth);
    imageView.setFitHeight(targetHeight);

    // calculate viewport
    imageView.setViewport((image.getHeight() / targetHeight < image.getWidth() / targetWidth)
            ? new Rectangle2D(0, 0, image.getHeight() / targetHeight * targetWidth, image.getHeight())
            : new Rectangle2D(0, 0, image.getWidth(), image.getWidth() / targetWidth * targetHeight));

    Region backgroundRegion = new Region();
    backgroundRegion.setPrefSize(targetWidth, targetHeight);
    backgroundRegion.setBackground(new Background(
            new BackgroundImage(
                    image,
                    BackgroundRepeat.NO_REPEAT,
                    BackgroundRepeat.NO_REPEAT,
                    BackgroundPosition.CENTER,
                    new BackgroundSize(0, 0, false, false, false, true) // cover
            )));

    HBox root = new HBox(imageView, backgroundRegion);
    root.setFillHeight(false);
    root.setPadding(new Insets(20));

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}

Другие вопросы по теме