Как обновить часть BufferedImage и отобразить ее с помощью javafx - PullRequest
0 голосов
/ 18 июня 2020

enter image description here У меня есть изображение. Вначале я хочу, чтобы изображение отображалось только с первым кадром. На клавиатуре с нажатой клавишей «u» выпейте воды и загрузите второй кадр. Если я правильно понял, все изображение должно быть загружено в начале. И тогда мне нужно установить новый y.
Как выполнить эту задачу? Как правильно отображать это изображение?
Мой код в:

package testDesktopUi;

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class DesktopUi extends Application {
    private static int y = 0;
    private static BufferedImage bufferedImage;
    private static final ImageView imageView = new ImageView();
    private static final HBox root = new HBox();

    @Override
    public void start(Stage primaryStage) throws IOException {
        String path = "Bottle.png";

        bufferedImage = ImageIO.read(new File(path)).getSubimage(0, 0, 32, 32);
        Image image = SwingFXUtils.toFXImage(bufferedImage, null);
        imageView.setImage(image);

        root.getChildren().add(imageView);
        Scene scene = new Scene(root);

        scene.setOnKeyPressed(key -> {
            if (key.getCode() == KeyCode.U) {
                System.out.println("u pressed");
                updateImage(bufferedImage);
                System.out.println(y);
            }
        });

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

    private static void updateImage(BufferedImage bufferedImage) {
        int maxHeight = 352;
        if (y + 32 >= maxHeight) {
            y = 0;
        } else {
            y += 32;
        }
        //?? bufferedImage.getSubimage(0, y, 32, 32);
    }
}

1 Ответ

3 голосов
/ 18 июня 2020

Если вы используете JavaFX, придерживайтесь только API изображений JavaFX: нет необходимости сначала загружать AWT BufferedImage и преобразовывать его в изображение JavaFX.

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

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;


public class DesktopUi extends Application {
    private int y = 0;
    private final ImageView imageView = new ImageView();
    private final HBox root = new HBox();

    @Override
    public void start(Stage primaryStage) {
        String path = "Bottle.png";

        // Assumes Bottle.png is in the same package as the current class:
        Image image = new Image(getClass().getResource("Bottle.png").toExternalForm());
        imageView.setImage(image);

        // display only a portion of the image:
        imageView.setViewport(new Rectangle2D(0, y, 32, 32));

        root.getChildren().add(imageView);
        Scene scene = new Scene(root);

        scene.setOnKeyPressed(key -> {
            if (key.getCode() == KeyCode.U) {
                System.out.println("u pressed");
                System.out.println(y);
                updateImage();
            }
        });

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

    private void updateImage() {

        // update y 
        int maxHeight = 352;
        if (y + 32 >= maxHeight) {
            y = 0;
        } else {
            y += 32;
        }

        // update portion of image displayed
        imageView.setViewport(new Rectangle2D(0, y, 32, 32));
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Обратите внимание, что это также хорошо подходит для анимации:

@Override
public void start(Stage primaryStage) {

    int numSprites = 11 ;

    Image image = new Image(getClass().getResource("Bottle.png").toExternalForm());
    imageView.setImage(image);

    IntegerProperty spriteIndex = new SimpleIntegerProperty();
    spriteIndex.addListener((obs, oldIndex, newIndex) -> System.out.println(newIndex));
    imageView.viewportProperty().bind(Bindings.createObjectBinding(
            () -> new Rectangle2D(0, spriteIndex.get() * 32 , 32, 32),
            spriteIndex
    ));

    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(5),
            new KeyValue(spriteIndex, numSprites - 1)));
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.play();

    root.getChildren().add(imageView);
    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...