javafx - 在调整图像大小以保持宽高比后访问图像的高度和宽度值

javafx - access height and width values of an image after it is resized to preserve aspect ratio

大家好,感谢阅读。我目前正在构建一个图像注释工具。图像被加载并绑定到父容器(borderpane)。纵横比也被保留。附加的代码片段说明了这些要点。

     imageView.setPreserveRatio(true);
     imageView.setSmooth(true);
     imageView.fitHeightProperty().bind(heightProperty());
     imageView.fitWidthProperty().bind(widthProperty());

效果很好:图像适合 window,并在 window 调整大小时调整大小。

在此之上,我放置了一个 canvas,用户可以在其上绘制矩形。在他们绘制了一个矩形之后,将启动一个弹出窗口,他们可以在其中编写注释。保存后,用户可以将鼠标悬停在绘制的矩形上,注释就会出现。

我想知道是否可以在调整图像大小以适应 window 之后访问图像的高度和宽度值,并且在 window 正在调整大小。

我需要这个的原因是我希望 canvas 镜像图像的尺寸,以便注释在其范围内。当前,当 window 调整大小时,注释不会保留 'fixed' 到它们的区域,因为 canvas 设置为 window 而非图像的尺寸。

如有任何帮助,我们将不胜感激。我有点碰壁了。而且我什至不确定我所问的在 JavaFX 中是否可行。再次感谢阅读。

大家晚上好。以下是我如何设法为将来可能需要帮助解决类似问题的任何人解决我的问题。

首先,使用以下代码创建一个 'Resizable Canvas':

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;  

class ResizableCanvas extends Canvas {

        public ResizableCanvas() {

            // Redraw canvas when size changes.

            widthProperty().addListener(evt -> draw());

            heightProperty().addListener(evt -> draw());

        }

        private void draw() {

            double width = getWidth();

            double height = getHeight();

            GraphicsContext gc = getGraphicsContext2D();

            gc.clearRect(0, 0, width, height);

            gc.setStroke(Color.RED);

            gc.strokeLine(0, 0, width, height);

            gc.strokeLine(0, height, width, 0);
        }
    @Override

        public boolean isResizable() {

            return true;
        }


    @Override

        public double prefWidth(double height) {

            return getWidth();

        }

        @Override

        public double prefHeight(double width) {

            return getHeight();

        }

    }

大功告成,按如下方式设置舞台:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;


public class ImageViewTest extends Application   {

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

@Override
public void start(Stage stage) throws Exception {

    ResizableCanvas rc = new ResizableCanvas();
    rc.setOnMouseEntered(e -> {
        System.out.println("entered ");
    });
    Image image = new Image("rushmore.png");

    ImageView imageView = new ImageView();
    imageView.setImage(image);
    imageView.setSmooth(true);
    imageView.setCache(true);


    AnchorPane rootAnchorPane = new AnchorPane();
    AnchorPane resizableCanvasAnchorPane = new AnchorPane();


   rc.widthProperty().bind(resizableCanvasAnchorPane.widthProperty());
 rc.heightProperty().bind(resizableCanvasAnchorPane.heightProperty());


    imageView.fitWidthProperty().bind(stage.widthProperty());
    imageView.fitHeightProperty().bind(stage.heightProperty());
    imageView.setPreserveRatio(true);

    //here's where the 'magic happens'
    resizableCanvasAnchorPane.getChildren().addAll(imageView, rc);
    rootAnchorPane.getChildren().addAll(resizableCanvasAnchorPane,rc);

    Scene scene = new Scene(rootAnchorPane);
    scene.setFill(Color.BLACK);
    stage.setTitle("ImageView Test");
    stage.setWidth(415);
    stage.setHeight(200);
    stage.setScene(scene);
    stage.show(); 
   }

}

非常感谢 Dirk Lemmermann 和本教程:

https://www.javacodegeeks.com/2014/04/javafx-tip-1-resizable-canvas.html

希望您能看到 canvas 随图像调整大小。图像上有红色指导线和鼠标事件来说明这一点。检查 IDE 的控制台,您可以看到当鼠标位于 canvas 范围内时触发的事件。

有任何问题,请告诉我。

干杯!