Thursday, January 10, 2013

Auto fit JavaFX 2 ImageView

Previous articles demonstrate how to "Load image with JavaFX FileChooser" and "Display large image on ImageView with ScrollPane". We can also make the ImageView auto fit to the image size.

Example:
auto-fit ImageView with large image
auto-fit ImageView with large image

auto-fit ImageView with small image
auto-fit ImageView with small image


package javafxpixel;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.imageio.ImageIO;

/**
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXPixel extends Application {
    
    ImageView myImageView;
    
    @Override
    public void start(Stage primaryStage) {
        
        Button btnLoad = new Button("Load");
        btnLoad.setOnAction(btnLoadEventListener);
        
        myImageView = new ImageView();

        VBox rootBox = new VBox();
        rootBox.getChildren().addAll(btnLoad, myImageView);
        
        Scene scene = new Scene(rootBox, 300, 300);
        
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
    EventHandler<ActionEvent> btnLoadEventListener
    = new EventHandler<ActionEvent>(){

        @Override
        public void handle(ActionEvent t) {
            FileChooser fileChooser = new FileChooser();
            
            //Set extension filter
            FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG");
            FileChooser.ExtensionFilter extFilterPNG = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.PNG");
            fileChooser.getExtensionFilters().addAll(extFilterJPG, extFilterPNG);
             
            //Show open file dialog
            File file = fileChooser.showOpenDialog(null);
                      
            try {
                BufferedImage bufferedImage = ImageIO.read(file);
                Image image = SwingFXUtils.toFXImage(bufferedImage, null);
                myImageView.setImage(image);
                myImageView.setFitWidth(300);
                myImageView.setPreserveRatio(true);
                
                /*
                 * Sets the value of the property smooth.
                 * 
                 * If set to true a better quality filtering will be used,
                 * if set to false a faster but lesser quality filtering will 
                 * be used.
                 */
                myImageView.setSmooth(true);
                
                /*
                 * Sets the value of the property cache.
                 * 
                 * A performance hint to the system to indicate that this Node 
                 * should be cached as a bitmap. Rendering a bitmap 
                 * representation of a node will be faster than rendering 
                 * primitives in many cases, especially in the case of 
                 * primitives with effects applied (such as a blur). 
                 * However, it also increases memory usage. This hint indicates 
                 * whether that trade-off (increased memory usage for increased 
                 * performance) is worthwhile. Also note that on some platforms 
                 * such as GPU accelerated platforms there is little benefit 
                 * to caching Nodes as bitmaps when blurs and other effects 
                 * are used since they are very fast to render on the GPU. 
                 * The cacheHintProperty() variable provides additional options 
                 * for enabling more aggressive bitmap caching.
                 * 
                 * Caching may be disabled for any node that has a 3D transform 
                 * on itself, any of its ancestors, or any of its descendants.
                 */
                
                myImageView.setCache(true);
                
            } catch (IOException ex) {
                Logger.getLogger(JavaFXPixel.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    };
}


Compare with "Load a re-sized image".

Next:
- Set fitWidth and fitHeight properties dynamically

2 comments:

  1. What is the purpose of the myImageView.setFitWidth(300) ? Why 300?

    ReplyDelete
    Replies
    1. 300 pixel or something else ? Only width of course

      Delete