1
votes

As a part of image processing application I need to create simple viewer module with zooming, scrolling and vector overlay features. Images are quite big: ~40000x20000 which makes operations on ImageView slow, buffering, etc. What are the best options to improve user experience when working with huge images in JavaFX?

1
Did you ever figure out how to make this performant? I'm trying to put this blue marble image as a background and running into similar issues. Caching isn't helping.ruckc
I decided to use tiled pane implementation like here: gist.github.com/james-d/a249470377fb3c58784a9349a22641c4 It's multithread, and you can implement cache for this solution quite easy. Of course you have to use image format that support partial reading from defined pixel.fatman

1 Answers

0
votes

I have a 8k by 4k image that scales fine by caching the scroll pane I have have placed it in and using this code for zooming. Only problem with scroll pane and large images is that panning is horrible and slow which I'm trying to find a solution for in my current application.

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()));
        }
    });