如何在JavaFX中有效地滚动和缩放大图像?

时间:2016-10-22 08:36:15

标签: java javafx

作为图像处理应用程序的一部分,我需要创建具有缩放,滚动和矢量叠加功能的简单查看器模块。图像非常大:~40000x20000,这使得ImageView上的操作变慢,缓冲等等。在JavaFX中处理大图像时,改善用户体验的最佳选择是什么?

1 个答案:

答案 0 :(得分:0)

我有一个8k乘4k的图像,可以通过缓存我已放入的滚动窗格并使用此代码进行缩放来进行精确缩放。只有滚动窗格和大图像的问题是平移是可怕的和缓慢的,我正试图在我当前的应用程序中找到解决方案。

final double SCALE_DELTA = 1.175;
private double SCALE_TOTAL = 1;

    //Adds functionality to scrolling
    mapScroll.addEventFilter(ScrollEvent.ANY, e ->{
        //Consumes the event
        e.consume();
        if(e.getDeltaY() == 0)
        {
            return;
        }
        double scaleFactor =
                  (e.getDeltaY() > 0)
                    ? SCALE_DELTA
                    : 1/SCALE_DELTA;
        //Ensures that you do not exceed the limits of the map
        if(scaleFactor * SCALE_TOTAL >= 1)
        {
            Bounds viewPort = mapScroll.getViewportBounds();
            Bounds contentSize = mapGrid.getBoundsInParent();

            double centerPosX = (contentSize.getWidth() - viewPort.getWidth()) * mapScroll.getHvalue() + viewPort.getWidth() / 2;
            double centerPosY = (contentSize.getHeight() - viewPort.getHeight()) * mapScroll.getVvalue() + viewPort.getHeight() / 2;

            mapGrid.setScaleX(mapGrid.getScaleX() * scaleFactor);
            mapGrid.setScaleY(mapGrid.getScaleY() * scaleFactor);
            SCALE_TOTAL *= scaleFactor;

            double newCenterX = centerPosX * scaleFactor;
            double newCenterY = centerPosY * scaleFactor;

            mapScroll.setHvalue((newCenterX - viewPort.getWidth()/2) / (contentSize.getWidth() * scaleFactor - viewPort.getWidth()));
            mapScroll.setVvalue((newCenterY - viewPort.getHeight()/2) / (contentSize.getHeight() * scaleFactor  -viewPort.getHeight()));
        }
    });