Drawing user input on Image JavaFX

点点圈 提交于 2020-02-20 10:51:13

问题


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:


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:


this Canvas tutorial by Oracle shows exactly what you want to accomplish in the "Interacting with the User" section.

It shows how you can add an EventHandler to the Canvas to handle MouseEvent such as MouseEvent.MOUSE_DRAGGED. The GraphicsContext is then used to get the x and y coordinates and draw on the canvas.

In order to use the Canvas outside the main Application class, you'd declare the Canvas in your .fxml file as such:

<BorderPane fx:controller="controllers.MyController" 
  xmlns:fx="http://javafx.com/fxml">
    <Canvas fx:id="drawArea" height="..." width="..."/>
</BorderPane>

Then, on your MyController class:

public class MyController implements Initializable {
  @FXML
  private Canvas drawArea;
  private GraphicsContext gc;

  @Override
  public void initialize(URL location, ResourceBundle resources) {
    gc = drawArea.getGraphicsContext2D();
    // Java 8 syntax, beware!
    drawArea.setOnMouseDragged(event -> gc.fillRect(event.getX(), event.getY(), 5, 5));
  }
}


来源:https://stackoverflow.com/questions/24681018/drawing-user-input-on-image-javafx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!