JavaFX image browsing and zooming

1. Effect display

Show results:

 Style image:

2. Code


import com.tobiasy.applet.pdf.utils.FileUtils;
import com.tobiasy.applet.pdf.utils.ResourceUtils;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.File;
import java.io.FileInputStream;

public class ImagesViewer extends Application {

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

    public ImagesViewer() {
    }

    public ImagesViewer(String title, String url) {
        this.title = title;
        this.url = url;
    }

    private static double size = 1;
    private static double count = 1.0;

    @Override
    public void start(Stage primary) {
        AnchorPane root = new AnchorPane();
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setStyle("-fx-border-color: #ffffff;-fx-background-color: #ffffff;");
        root.getChildren().add(scrollPane);

        Image image = new Image(url);
        double width = image.getWidth();
        double height = image.getHeight();
        double percent = 1000 / image.getWidth() < 600 / image.getHeight() ? 1000 / image.getWidth() : 600 / image.getHeight();
        if (percent < 1) {
            width = width * percent;
            height = height * percent;
        }

        VBox vBox = new VBox();
        vBox.setPrefWidth(1000);
        vBox.setPrefHeight(600);
        vBox.setAlignment(Pos.CENTER);
        scrollPane.setContent(vBox);

        ImageView imageView = new ImageView();
        imageView.setImage(image);
        imageView.setFitWidth(width);
        imageView.setFitHeight(height);
        vBox.getChildren().add(imageView);
        size = 1;
        count = 1;
        imageView.setOnScroll(event -> {
            if (event.getDeltaY() > 0) {
                count = count + 1.0 / 10;
                size = 1.0 / 200 * (count - 1) * (count - 1) * (count - 1) + 1;
                imageView.setFitWidth(imageView.getFitWidth() * size);
                imageView.setFitHeight(imageView.getFitHeight() * size);
                count++;
            } else {
                count = count - 1.0 / 10;
                double y = 1.0 / 200 * (count - 1) * (count - 1) * (count - 1) + 1;
                size = y < 0 ? size : y;
                imageView.setFitWidth(imageView.getFitWidth() / size);
                imageView.setFitHeight(imageView.getFitHeight() / size);
                count--;
            }
        });

        Scene scene = new Scene(root);
        primary.setTitle(title);
        // 设置软件头部icon
//        File iconFile = ResourceUtils.getIconFile();
//        FileInputStream inputStream = FileUtils.getFileInputStream(iconFile);
//        primary.getIcons().add(new Image(inputStream));
        primary.setScene(scene);
        primary.setWidth(1000);
        primary.setHeight(700);
        primary.show();
    }

    private String title = "图片浏览器";
    private String url = "https://img.zcool.cn/community/015ede57b04f050000018c1b1409b4.JPG?x-oss-process=image/auto-orient,1";
}

3. Core code explanation

3.1 Image scaling core code

        count = count - 1.0 / 10;
        double y = 1.0 / 200 * (count - 1) * (count - 1) * (count - 1) + 1;
        size = y < 0 ? size : y;
        imageView.setFitWidth(imageView.getFitWidth() / size);
        imageView.setFitHeight(imageView.getFitHeight() / size);
        count--;

        This is the core code for image reduction. It can be seen from the first line that the width is reduced by 1/10 pixels each time. Secondly, a cubic function is seen in the second line, which is used to reduce the smoothness. Here we will talk about it first. Why use it, if the width is reduced by 1/10 each time, when the width is small, the image will be reduced more and more slowly, so I don't want it to be scaled proportionally, but I want it to shrink as the image shrinks Faster and faster, but here we can also set the corresponding speed according to the demand, so we probably know the image of this function:

 The horizontal axis represents the count (image width) in the code, and the vertical axis represents the size (magnification factor). It can be seen from the image that when the image width is reduced (less than 1 direction), the smaller the reduction, the greater the slope, in other words The faster the zoom out, the same reason, the zoom in is the same, so that we can successfully solve the problems we encountered above.

3.2 Set the software header icon

        File iconFile = ResourceUtils.getIconFile();
        FileInputStream inputStream = FileUtils.getFileInputStream(iconFile);
        primary.getIcons().add(new Image(inputStream));

First, we may obtain a File object, then obtain its input stream through the File object, then create an Image object through the input stream, and finally add the Image object to the Stage object.

3.3 Calculating the aspect ratio of the picture

        double width = image.getWidth();
        double height = image.getHeight();
        double percent = 1000 / image.getWidth() < 600 / image.getHeight() ? 1000 / image.getWidth() : 600 / image.getHeight();
        if (percent < 1) {
            width = width * percent;
            height = height * percent;
        }

        In the calculation of the third line, we just want to get the most ratio. This ratio just puts the picture in a 1000*600 container. The purpose of doing this here is to adapt to both length > width and width > length pictures , all in all, it is to zoom and display the picture that is longer than 1000 or wider than 600.

3.4 Mouse scroll event

        We mentioned image scaling above, what operation is used to achieve it here, in fact, it is achieved by scrolling the mouse, then let's take a look at the function triggered by the scroll event:

        imageView.setOnScroll(event -> {
            // 缩放具体逻辑
            if (event.getDeltaY() > 0) {
                // 这里是向上滚动滚轮(即放大图片)
            } else {
                // 这里是乡下滚动滚轮(即缩小图片)
            }
        }

        The code has been posted, and specific event processing has been added, and the core zoom image logic embedded inside will be fine.

        In addition to the core code, there are other relatively simple javafx grammars. If you want to continue learning javafx, please continue to pay attention to my article, thank you.

Just copy the code and try it out

Guess you like

Origin blog.csdn.net/m0_37649480/article/details/125941031