2013-08-15 17 views
5

Ich möchte Bild auf Leinwand gedreht drehen. mit drawImage(image, 0, 0) kann ich ein Bild zeichnen, aber wie kann ich das Bild zum Beispiel 45 Grad drehen und zeichnen und dann ein anderes Bild mit -50 Grad Drehung nach dem vorherigen Bild auf der gleichen Leinwand zeichnen?Wie zeichne ich ein Bild auf JavaFX Canvas gedreht?

graphicContext2D funktioniert nicht für mich, weil es alle Leinwand Inhalte drehen.

Also wie kann ich das tun?

Antwort

15

Hier ist ein Beispiel, das ähnliche Prinzipien zu Katonas Antwort verfolgt. Einziger Unterschied ist, dass es Bilder um beliebige Drehpunkte dreht, indem es eine benutzerdefinierte Transformation anwendet.

rotatedimages

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.canvas.*; 
import javafx.scene.image.Image; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 

/** Rotates images round pivot points and places them in a canvas */ 
public class RotatedImageInCanvas extends Application { 
    /** 
    * Sets the transform for the GraphicsContext to rotate around a pivot point. 
    * 
    * @param gc the graphics context the transform to applied to. 
    * @param angle the angle of rotation. 
    * @param px the x pivot co-ordinate for the rotation (in canvas co-ordinates). 
    * @param py the y pivot co-ordinate for the rotation (in canvas co-ordinates). 
    */ 
    private void rotate(GraphicsContext gc, double angle, double px, double py) { 
     Rotate r = new Rotate(angle, px, py); 
     gc.setTransform(r.getMxx(), r.getMyx(), r.getMxy(), r.getMyy(), r.getTx(), r.getTy()); 
    } 

    /** 
    * Draws an image on a graphics context. 
    * 
    * The image is drawn at (tlpx, tlpy) rotated by angle pivoted around the point: 
    * (tlpx + image.getWidth()/2, tlpy + image.getHeight()/2) 
    * 
    * @param gc the graphics context the image is to be drawn on. 
    * @param angle the angle of rotation. 
    * @param tlpx the top left x co-ordinate where the image will be plotted (in canvas co-ordinates). 
    * @param tlpy the top left y co-ordinate where the image will be plotted (in canvas co-ordinates). 
    */ 
    private void drawRotatedImage(GraphicsContext gc, Image image, double angle, double tlpx, double tlpy) { 
     gc.save(); // saves the current state on stack, including the current transform 
     rotate(gc, angle, tlpx + image.getWidth()/2, tlpy + image.getHeight()/2); 
     gc.drawImage(image, tlpx, tlpy); 
     gc.restore(); // back to original state (before rotation) 
    } 

    @Override public void start(Stage stage) { 
     Image image = new Image(
      "http://worldpress.org/images/maps/world_600w.jpg", 350, 0, true, true 
     ); 

     // creates a canvas on which rotated images are rendered. 
     Canvas canvas = new Canvas(600, 400); 
     GraphicsContext gc = canvas.getGraphicsContext2D(); 

     drawRotatedImage(gc, image, 40, 0, 0); 
     drawRotatedImage(gc, image, -50, 400, 200); 

     // supplies a tiled background image on which the canvas is drawn. 
     StackPane stack = new StackPane(); 
     stack.setMaxSize(canvas.getWidth(), canvas.getHeight()); 
     stack.setStyle("-fx-background-image: url('http://1.bp.blogspot.com/_wV5JMD1OISg/TDYTYxuxR4I/AAAAAAAAvSo/a0zT8nwPV8U/s400/louis-vuitton-nice-beautiful.jpg');"); 
     stack.getChildren().add(
       canvas 
     ); 

     // places a resizable padded frame around the canvas. 
     StackPane frame = new StackPane(); 
     frame.setPadding(new Insets(20)); 
     frame.getChildren().add(stack); 

     stage.setScene(new Scene(frame, Color.BURLYWOOD)); 
     stage.show(); 
    } 

    public static void main(String[] args) { launch(RotatedImageInCanvas.class); } 
} 
+0

Diese Lösung passt besser in meinem Fall. – Eeliya

3

Nun, ich nie JavaFX verwendet haben, aber Dokumentation es ist API Surfen, kam ich mit dieser Lösung (ich habe nicht wirklich versucht, es so ist es falsch sein kann):

Canvas canvas = ... 
Image img = ... 
GraphicsContext gc = canvas.getGraphicsContext2D(); 

gc.save(); // saves the current state on stack, including the current transform 
gc.rotate(45); 
gc.drawImage(img); 
gc.restore(); // back to original state (before rotation) 

gc.save(); 
gc.rotate(-50); 
gc.drawImage(img); 
gc.restore(); 

Ich weiß nicht, ob Es funktioniert hier, aber die Idee (Transformationsstapel) ist von anderen Zeichnungs-API (wie OpenGL) ausgeliehen.

2

Das obige Problem kann auch durch die Schaffung von verschiedenen Schichten der Leinwand gelöst werden.

private void createLayers(){ 
     // Layers 1&2 are the same size 
     layer1 = new Canvas(300,250); 
     layer2 = new Canvas(300,250); 

     // Obtain Graphics Contexts 
     gc1 = layer1.getGraphicsContext2D(); 
     gc1.setFill(Color.GREEN); 
     gc1.fillOval(50,50,20,20); 
     gc1.getCanvas().setRotate(45); 
     gc2 = layer2.getGraphicsContext2D(); 
     gc2.setFill(Color.BLUE); 
     gc2.fillOval(100,100,20,20); 
     gc.getCanvas().setRotate(135); 
    } 
     ... 

private void addLayers(){ 
     // Add Layers 
     borderPane.setTop(cb);   
     Pane pane = new Pane(); 
     pane.getChildren().add(layer1); 
     pane.getChildren().add(layer2); 
     layer1.toFront(); 
     borderPane.setCenter(pane);  
     root.getChildren().add(borderPane); 
    } 
Verwandte Themen