Drawing user input on Image JavaFX


Question

Suppose you have an app that displays user graphic (some kind of image) then you want to allow the user to draw some lines on this image. I have the following questions regarding such situation:

How would you accomplish that? How would you get pixel coordinates for the image from the user drag events? How would you update the image in real time?

1
2
7/14/2014 3:35:56 PM

I will give you an example of the exact opposite [erasing the Image on JavaFX] which I suppose will be enough as a starter point for you:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class EraseImageonCanvas extends Application {
    private Pane root = new Pane();
    private void setCanvas(Canvas canvas, Image img) {
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.drawImage(img, 0, 0,canvas.getWidth(), canvas.getHeight());
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Erasing the Image");
        Rectangle rect = new Rectangle(400, 400);
        drawBackground(rect);
        root.getChildren().add(rect);
        final Canvas canvas = new Canvas(200, 200);
        canvas.setTranslateX(100);
        canvas.setTranslateY(100);
        //For local images use         
        //image = new Image(getClass().getResource(#Path#).openStream());
        final Image image = new Image(
                "http://kyllo.com.br/wp-content/uploads/2013/12/Faroeste-Cabloco.jpg"
              );
        setCanvas(canvas,image);
        final GraphicsContext gc = canvas.getGraphicsContext2D();
        // Clear away portions as the user drags the mouse
        canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {
                gc.clearRect(e.getX() - 2, e.getY() - 2, 5, 5);
            }
        });

        // Reset the Canvas when the user double-clicks
        canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {            
                if (t.getClickCount() >1) {
                    setCanvas(canvas, image);
                }  
            }
        });

        // Add the Canvas to the Scene, and show the Stage
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

     //Draws the background with a RadialGradient 
    private void drawBackground(Rectangle rect) {
        rect.setFill(new LinearGradient(0, 0, 1, 1, true,
                CycleMethod.REFLECT,
                new Stop(0, Color.RED),
                new Stop(1, Color.YELLOW)));
    }
    public static void main(String[] args) {
        launch(args);
    }
}

Download it on gist

2
7/10/2014 6:48:07 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon