2016-10-22 187 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())); 
     } 
    });