在Image JavaFX上绘制用户输入

时间:2014-07-10 15:52:20

标签: javafx

假设您有一个显示用户图形(某种图像)的应用程序,那么您希望允许用户在此图像上绘制一些线条。关于这种情况我有以下问题:

你将如何实现这一目标? 您如何从用户拖动事件中获取图像的像素坐标? 你会如何实时更新图像?

2 个答案:

答案 0 :(得分:2)

我将举例说明完全相反 [删除JavaFX上的图像] 我认为足以作为起点

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);
    }
}

gist

上下载

答案 1 :(得分:1)

这个Canvas tutorial by Oracle在“与用户交互”部分中准确显示了您想要完成的任务。

它显示了如何向Canvas添加EventHandler以处理MouseEvent MouseEvent.MOUSE_DRAGGED。然后使用GraphicsContext获取x和y坐标并在画布上绘制。

为了在主Application类之外使用Canvas,你可以在.fxml文件中声明Canvas:

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

然后,在你的MyController类上:

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));
  }
}