Sunday, December 30, 2012

Take a snapshot of Scene with JavaFX

JavaFX 2.2 introduce a snapshot() method that enables you to take a picture of scene; simple call scene.snapshot(null), a WritableImage will be returned.

Take a snapshot of Scene with JavaFX


package testjavafx;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Slider;
import javafx.scene.control.SliderBuilder;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class TestJavaFX extends Application {
    
    PixelReader pixelReader;
    int width, height;
    
    WritableImage writableImage, writableImageHue, writableImageSaturation, writableImageBrightness;
    PixelWriter pixelWriter, pixelWriterHue, pixelWriterSaturation, pixelWriterBrightness;
    ImageView destImageView, imageViewHue, imageViewSaturation, imageViewBrightness;
    
    Slider sliderHue, sliderSaturation, sliderBrightness;
    double adjHue, adjSaturation, adjBrightness;
    
    @Override
    public void start(Stage primaryStage) {
        
        Image image = new Image("http://goo.gl/kYEQl");
        ImageView imageView = new ImageView();
        imageView.setImage(image);
        
        pixelReader = image.getPixelReader();
        width = (int)image.getWidth();
        height = (int)image.getHeight();
        
        //Copy from source to destination pixel by pixel
        writableImage = new WritableImage(width, height);
        pixelWriter = writableImage.getPixelWriter();
        
        writableImageHue = new WritableImage(width, height);
        pixelWriterHue = writableImageHue.getPixelWriter();
        
        writableImageSaturation = new WritableImage(width, height);
        pixelWriterSaturation = writableImageSaturation.getPixelWriter();
        
        writableImageBrightness = new WritableImage(width, height);
        pixelWriterBrightness = writableImageBrightness.getPixelWriter();
        
        destImageView = new ImageView();
        imageViewHue = new ImageView();
        imageViewSaturation = new ImageView();
        imageViewBrightness = new ImageView();
        
        HBox hBox_Image = new HBox();
        hBox_Image.getChildren().addAll(imageView, destImageView);
        
        //Control box for Hue
        sliderHue = SliderBuilder.create()
                .prefWidth(300)
                .min(-360)
                .max(360)
                .majorTickUnit(30)
                .showTickMarks(true)
                .showTickLabels(true)
                .value(0)
                .build();
        sliderHue.valueProperty().addListener(sliderChangeListener);
        HBox hBox_Hue = new HBox();
        hBox_Hue.getChildren().addAll(imageViewHue, sliderHue);
        
        //Control box for Saturation
        sliderSaturation = SliderBuilder.create()
                .prefWidth(300)
                .min(-1)
                .max(1)
                .majorTickUnit(0.2)
                .showTickMarks(true)
                .showTickLabels(true)
                .value(0)
                .build();
        sliderSaturation.valueProperty().addListener(sliderChangeListener);
        HBox hBox_Saturation = new HBox();
        hBox_Saturation.getChildren().addAll(imageViewSaturation, sliderSaturation);
        
        //Control box for Blue
        sliderBrightness = SliderBuilder.create()
                .prefWidth(300)
                .min(-1)
                .max(1)
                .majorTickUnit(0.2)
                .showTickMarks(true)
                .showTickLabels(true)
                .value(0)
                .build();
        sliderBrightness.valueProperty().addListener(sliderChangeListener);
        HBox hBox_Brightness = new HBox();
        hBox_Brightness.getChildren().addAll(imageViewBrightness, sliderBrightness);
        
        Button buttonSave = new Button("Snapshot");
        
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(hBox_Image, 
                hBox_Hue, hBox_Saturation, hBox_Brightness, buttonSave);

        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        final Scene scene = new Scene(root, 350, 350);
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
        
        updateImage();
        
        buttonSave.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                //Get snapshot image
                WritableImage snapImage = scene.snapshot(null);
                
                //display in new window
                ImageView snapView = new ImageView();
                snapView.setImage(snapImage);
                
                StackPane snapLayout = new StackPane();
                snapLayout.getChildren().add(snapView);
                
                Scene snapScene = new Scene(snapLayout, 350, 350);

                Stage snapStage = new Stage();
                snapStage.setTitle("Snapshot");
                snapStage.setScene(snapScene);
 
                snapStage.show();
            }
        });
    }
    
    ChangeListener<Number> sliderChangeListener
            = new ChangeListener<Number>(){

        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            updateImage();
        }
    };
    
    private void updateImage(){
        adjHue = sliderHue.valueProperty().doubleValue();
        adjSaturation = sliderSaturation.valueProperty().doubleValue();
        adjBrightness = sliderBrightness.valueProperty().doubleValue();
        
        for (int y = 0; y < height; y++){
            for (int x = 0; x < width; x++){
                Color color = pixelReader.getColor(x, y);
                pixelWriter.setColor(x, y, color);
                
                double hue = color.getHue() + adjHue;
                if(hue > 360.0){
                    hue = hue - 360;
                }else if(hue < 0.0){
                    hue = hue + 360.0;
                }
                
                double saturation = color.getSaturation() + adjSaturation;
                if(saturation > 1.0){
                    saturation = 1.0;
                }else if(saturation < 0.0){
                    saturation = 0.0;
                }
                
                double brightness = color.getBrightness() + adjBrightness;
                if(brightness > 1.0){
                    brightness = 1.0;
                }else if(brightness < 0.0){
                    brightness = 0.0;
                }
                
                double opacity = color.getOpacity();
                
                pixelWriterHue.setColor(x, y, new Color(hue/360.0, hue/360.0, hue/360.0, opacity));
                pixelWriterSaturation.setColor(x, y, new Color(saturation, saturation, saturation, opacity));
                pixelWriterBrightness.setColor(x, y, new Color(brightness, brightness, brightness, opacity));
                
                Color newColor = Color.hsb(hue, saturation, brightness, opacity);
                pixelWriter.setColor(x, y, newColor);

            }
        }
        
        imageViewHue.setImage(writableImageHue);
        imageViewSaturation.setImage(writableImageSaturation);
        imageViewBrightness.setImage(writableImageBrightness);
        destImageView.setImage(writableImage);
    }

    public static void main(String[] args) {
        launch(args);
    }
}


Related:
- Take a snapshot of Node with JavaFX

No comments:

Post a Comment