2016-10-22 59 views
1

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

+0

你有没有想过如何使这个性能?我试图将[蓝色大理石图像](https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73909/world.topo.bathy.200412.3x21600x10800.png)作为背景,类似的问题。缓存不起作用。 – ruckc

+0

我决定使用像这样的平铺窗格实现:https://gist.github.com/james-d/a249470377fb3c58784a9349a22641c4 它是多线程的,你可以很容易地为这个解决方案实现缓存。当然,您必须使用支持从定义像素进行部分读取的图像格式。 – fatman

回答

0

当你第一次运行你的应用程序,你的尺寸的情景就像这样:

Scene scene = new Scene(scrollPane, zoom.get()*4, zoom.get()*3); 

相反,如果你的尺寸的情景:

Scene scene = new Scene(scrollPane, zoom.get()*4 + 2, zoom.get()*3 + 2); 

那么当第一次显示了现场,图像将完全显示并填充滚动窗格。

这是滚动窗格的默认CSS供您参考。

.scroll-pane { 
    -fx-skin: "com.sun.javafx.scene.control.skin.ScrollPaneSkin"; 
    -fx-background-color: -fx-box-border,-fx-background; 
    -fx-background-insets: 0, 1; 
    -fx-padding: 1.0; 
} 

欲了解更多请点击here

0

我必须通过扩展,通过缓存我已经将其放置在滚动窗格中使用此代码进行变焦精细4K图像的8K。只有滚动窗格和大图像的问题是,平移是可怕的和缓慢的,我试图找到一个在我当前的应用程序的解决方案。

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