JavaFx 缩放和平移覆盖固定比例标签的图像
Posted
技术标签:
【中文标题】JavaFx 缩放和平移覆盖固定比例标签的图像【英文标题】:JavaFx zooming and panning an image with overlaid fixed scale labels 【发布时间】:2021-11-10 21:04:07 【问题描述】:我是一所大学的医生,我正在开发 X 射线分析软件,在该软件中,用户通过将小圆圈放置在 X 射线图像上来定义解剖点。到目前为止我很满意,但是我需要根据鼠标位置使用鼠标滚轮实现缩放和平移。
为了清晰起见,我简化了我的代码,原来的代码比这复杂得多。
在此算法中,点在缩放和平移时不应根据图像移动,因此它们的位置保持不变,并且点附近的标签在缩放时必须保持相同的字体大小(我们不希望看到巨大的标签)。我被困在这一点上。
请帮忙,你能生成这个算法吗?
示例如下:
这是我的java代码:
package main.java;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Circle;
public class ZoomClass
@FXML
AnchorPane xRayAnchorPane;
@FXML
ImageView xRayImage;
@FXML
ScrollPane xRayScrollPane;
@FXML
Label pointsLabel;
public void initialize()
xRayImage.setOnMouseClicked(mouseEvent ->
if(mouseEvent.getButton().equals(MouseButton.PRIMARY)) // ADD POINTS
Circle circle = new Circle();
circle.setCenterX(mouseEvent.getX()+58); // Some Offset values to proper positioning
circle.setCenterY(mouseEvent.getY()+75); // Some Offset values to proper positioning
circle.setRadius(2);
xRayAnchorPane.getChildren().add(circle); // Adding circle to mainFrame
pointsLabel.setText("A"); // Defining the point's name
pointsLabel.setLayoutX(circle.getCenterX()+5); // Some Offset values to proper positioning
pointsLabel.setLayoutY(circle.getCenterY()); // Some Offset values to proper positioning
);
还有我的 FXML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="650.0" prefWidth="851.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.java.ZoomClass" fx:id="xRayAnchorPane">
<children>
<ScrollPane layoutX="56.0" layoutY="71.0" prefHeight="533.0" prefWidth="743.0" fx:id="xRayScrollPane">
<content>
<ImageView fitHeight="736.0" fitWidth="739.0" pickOnBounds="true" preserveRatio="true" fx:id="xRayImage">
<image>
<Image url="@ceph2.jpg" />
</image>
</ImageView>
</content>
</ScrollPane>
<Label fx:id="pointsLabel" layoutX="14.0" layoutY="138.0" />
</children>
</AnchorPane>
【问题讨论】:
这个问题一直很好,直到它询问“你能不能生成这个算法” -> 通常,*** 不能那样工作。 我很抱歉,但我不是专业开发人员,也不熟悉高级算法,请原谅我的无知,我不知道在哪里问 我明白,这不是批评,只是对 *** 正常工作方式的解释,以设定期望。您可能会从像Gluon 这样的公司获得咨询服务。请注意,我与他们没有任何关系,我只是将它们链接起来,因为你注意到你不知道在哪里问。 我编辑了问题以解决一些语法问题,希望编辑不会改变问题中任何内容的意图或含义(如果有,请重新编辑以修复它)。发帖时,我建议非以英语为母语的人以及以英语为母语的人使用Grammarly。它有助于修复许多无意的错误。 看看this能不能帮上忙。 【参考方案1】:根据this的问题,您需要为要放大的元素创建一个组元素。当您创建新圈子时,您应该添加到缩放组。最后,对您创建的组元素应用缩放
【讨论】:
【参考方案2】:这有帮助吗?
比例因子仅在 ImageView 上通过按住 CTRL 的鼠标滚轮进行设置。 标签放置在 ScrollPane 之外的 AnchorPane 中,因此它们不受您需要的平移和缩放的影响。
package com.***.zoom;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.input.ZoomEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Zoomer extends Application
private AnchorPane ap;
private ImageView imgView;
private char markTxt = 'A';
public static void main(String[] args)
launch(args);
@Override
public void start(Stage primaryStage) throws Exception
ap = new AnchorPane();
Image img = new Image("https://upload.wikimedia.org/wikipedia/commons/d/dc/Medical_X-Ray_imaging_SEQ07_nevit.jpg");
imgView = new ImageView(img);
ScrollPane sp = new ScrollPane(imgView);
AnchorPane.setTopAnchor(sp, 0.0);
AnchorPane.setLeftAnchor(sp, 0.0);
AnchorPane.setBottomAnchor(sp, 0.0);
AnchorPane.setRightAnchor(sp, 0.0);
ap.getChildren().add(sp);
imgView.setOnMouseClicked(this::onClick);
imgView.setOnScroll(this::imageScrolled);
Scene scene = new Scene(ap);
primaryStage.setTitle("Zoom Image");
primaryStage.setScene(scene);
primaryStage.show();
public void onClick(MouseEvent event)
if (event.getButton() == MouseButton.PRIMARY)
placeMarker(event.getSceneX(), event.getSceneY());
private void imageScrolled(ScrollEvent event)
// When holding CTRL mouse wheel will be used for zooming
if (event.isControlDown())
double delta = event.getDeltaY();
double adjust = delta / 1000.0;
double zoom = Math.min(10, Math.max(0.1, imgView.getScaleX() + adjust));
setImageZoom(zoom);
event.consume();
private void placeMarker(double sceneX, double sceneY)
Circle circle = new Circle(2);
circle.setStroke(Color.RED);
circle.setTranslateY(-12);
Label marker = new Label(String.valueOf(markTxt), circle);
marker.setTextFill(Color.RED);
markTxt++;
Point2D p = ap.sceneToLocal(sceneX, sceneY);
AnchorPane.setTopAnchor(marker, p.getY());
AnchorPane.setLeftAnchor(marker, p.getX());
ap.getChildren().add(marker);
private void setImageZoom(double factor)
imgView.setScaleX(factor);
imgView.setScaleY(factor);
【讨论】:
感谢您的努力,但它仍然不能平移和滚动,不是我要找的东西。 我不明白你的意思。在我的示例中,图像是可平移和可滚动的。以上是关于JavaFx 缩放和平移覆盖固定比例标签的图像的主要内容,如果未能解决你的问题,请参考以下文章