我需要缩放或缩放图像,但是当我尝试缩放它时,它始终位于左上角的中心。如何根据自己的喜好从中心或其他任何地方缩放?
完整链接project
@FXML
void plusButton(ActionEvent event) throws IOException {
double height = ImageView.getFitHeight();
double width = ImageView.getFitWidth();
ImageView.setFitHeight(height + 100);
ImageView.setFitWidth(width + 100);
//TODO
//Rectangle2D rectangle2D = new Rectangle2D(800, 800, 800, 800);
//ImageView.setViewport(rectangle2D);
}
原因是您要更改ImageView
的整个宽度和高度,它是Image
的容器。为了在JavaFX
中缩放或缩放图像,您需要使用ViewPort
中的ImageView
。
无论何时放大或缩小,都需要设置新的ViewPort
。
imageView.setViewport(new Rectangle2D(minX, minY, width, height));
- 参数:
minX
-Rectangle2D
左上角的x坐标>- [
minY
-Rectangle2D
]左上角的y坐标>- [
width
-Rectangle2D
的宽度height
-Rectangle2D
的高度我没有调试您的代码,但是以下代码会很有帮助。尝试对其进行调整并学习概念,然后将更改应用于代码要容易得多。
import javafx.application.Application; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.geometry.Insets; import javafx.geometry.Point2D; import javafx.geometry.Pos; import javafx.geometry.Rectangle2D; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Hyperlink; import javafx.scene.control.Tooltip; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class PlutoExplorer extends Application { private static final String IMAGE_CREDIT_URL = "http://www.nasa.gov/image-feature/global-mosaic-of-pluto-in-true-color"; private static final String IMAGE_URL = "https://www.nasa.gov/sites/default/files/thumbnails/image/global-mosaic-of-pluto-in-true-color.jpg"; private static final int MIN_PIXELS = 10; @Override public void start(Stage primaryStage) { Image image = new Image(IMAGE_URL); double width = image.getWidth(); double height = image.getHeight(); ImageView imageView = new ImageView(image); imageView.setPreserveRatio(true); reset(imageView, width / 2, height / 2); ObjectProperty<Point2D> mouseDown = new SimpleObjectProperty<>(); imageView.setOnMousePressed(e -> { Point2D mousePress = imageViewToImage(imageView, new Point2D(e.getX(), e.getY())); mouseDown.set(mousePress); }); imageView.setOnMouseDragged(e -> { Point2D dragPoint = imageViewToImage(imageView, new Point2D(e.getX(), e.getY())); shift(imageView, dragPoint.subtract(mouseDown.get())); mouseDown.set(imageViewToImage(imageView, new Point2D(e.getX(), e.getY()))); }); imageView.setOnScroll(e -> { double delta = e.getDeltaY(); Rectangle2D viewport = imageView.getViewport(); double scale = clamp(Math.pow(1.01, delta), // don't scale so we're zoomed in to fewer than MIN_PIXELS in any direction: Math.min(MIN_PIXELS / viewport.getWidth(), MIN_PIXELS / viewport.getHeight()), // don't scale so that we're bigger than image dimensions: Math.max(width / viewport.getWidth(), height / viewport.getHeight()) ); Point2D mouse = imageViewToImage(imageView, new Point2D(e.getX(), e.getY())); double newWidth = viewport.getWidth() * scale; double newHeight = viewport.getHeight() * scale; // To keep the visual point under the mouse from moving, we need // (x - newViewportMinX) / (x - currentViewportMinX) = scale // where x is the mouse X coordinate in the image // solving this for newViewportMinX gives // newViewportMinX = x - (x - currentViewportMinX) * scale // we then clamp this value so the image never scrolls out // of the imageview: double newMinX = clamp(mouse.getX() - (mouse.getX() - viewport.getMinX()) * scale, 0, width - newWidth); double newMinY = clamp(mouse.getY() - (mouse.getY() - viewport.getMinY()) * scale, 0, height - newHeight); imageView.setViewport(new Rectangle2D(newMinX, newMinY, newWidth, newHeight)); }); imageView.setOnMouseClicked(e -> { if (e.getClickCount() == 2) { reset(imageView, width, height); } }); Hyperlink link = new Hyperlink("Image Credit: NASA/JHUAPL/SwRI"); link.setOnAction(e -> getHostServices().showDocument(IMAGE_CREDIT_URL)); link.setPadding(new Insets(10)); link.setTooltip(new Tooltip(IMAGE_CREDIT_URL)); HBox buttons = createButtons(width, height, imageView); Tooltip tooltip = new Tooltip("Scroll to zoom, drag to pan"); Tooltip.install(buttons, tooltip); Pane container = new Pane(imageView); container.setPrefSize(800, 600); imageView.fitWidthProperty().bind(container.widthProperty()); imageView.fitHeightProperty().bind(container.heightProperty()); VBox root = new VBox(link, container, buttons); root.setFillWidth(true); VBox.setVgrow(container, Priority.ALWAYS); primaryStage.setScene(new Scene(root)); primaryStage.setTitle("Pluto explorer"); primaryStage.show(); } private HBox createButtons(double width, double height, ImageView imageView) { Button reset = new Button("Reset"); reset.setOnAction(e -> reset(imageView, width / 2, height / 2)); Button full = new Button("Full view"); full.setOnAction(e -> reset(imageView, width, height)); HBox buttons = new HBox(10, reset, full); buttons.setAlignment(Pos.CENTER); buttons.setPadding(new Insets(10)); return buttons; } // reset to the top left: private void reset(ImageView imageView, double width, double height) { imageView.setViewport(new Rectangle2D(0, 0, width, height)); } // shift the viewport of the imageView by the specified delta, clamping so // the viewport does not move off the actual image: private void shift(ImageView imageView, Point2D delta) { Rectangle2D viewport = imageView.getViewport(); double width = imageView.getImage().getWidth() ; double height = imageView.getImage().getHeight() ; double maxX = width - viewport.getWidth(); double maxY = height - viewport.getHeight(); double minX = clamp(viewport.getMinX() - delta.getX(), 0, maxX); double minY = clamp(viewport.getMinY() - delta.getY(), 0, maxY); imageView.setViewport(new Rectangle2D(minX, minY, viewport.getWidth(), viewport.getHeight())); } private double clamp(double value, double min, double max) { if (value < min) return min; if (value > max) return max; return value; } // convert mouse coordinates in the imageView to coordinates in the actual image: private Point2D imageViewToImage(ImageView imageView, Point2D imageViewCoordinates) { double xProportion = imageViewCoordinates.getX() / imageView.getBoundsInLocal().getWidth(); double yProportion = imageViewCoordinates.getY() / imageView.getBoundsInLocal().getHeight(); Rectangle2D viewport = imageView.getViewport(); return new Point2D( viewport.getMinX() + xProportion * viewport.getWidth(), viewport.getMinY() + yProportion * viewport.getHeight()); } public static void main(String[] args) { launch(args); } }
上述代码是从GitHub导入的。