2013-08-15 14 views
5

Voglio disegnare un'immagine su tela ruotata. con drawImage(image, 0, 0) Posso disegnare un'immagine ma come posso ruotare quell'immagine ad esempio 45 gradi e disegnarla e quindi disegnare un'altra immagine con una rotazione di -50 gradi dopo l'immagine precedente sulla stessa tela?Come disegnare un'immagine ruotata su JavaFX Canvas?

graphicContext2D non funziona per me perché ruota tutto il contenuto del canvas.

Quindi, come posso farlo?

risposta

15

Ecco un esempio, seguendo principi simili alla risposta di Katona, l'unica differenza è che ruota le immagini su punti di rotazione arbitrari applicando una trasformazione personalizzata.

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

Questa soluzione si adatta meglio nel mio caso. – Eeliya

3

Beh non ho mai usato JavaFX, ma la navigazione si tratta di documentazione delle API, mi si avvicinò con questa soluzione (non ho davvero provato quindi potrebbe essere sbagliato):

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

Non so se funziona qui, ma l'idea (stack di trasformazione) è presa in prestito da altre API di disegno (come OpenGL).

2

Il problema di cui sopra può anche essere risolto creando diversi strati di tela.

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