Let's see if I was able to understand your question...
how to rotate Image only without rotating the whole GraphicsContext?
You can't do that using just a GraphicsContext. You need to rotate the GraphicsContext to get a rotated image rendered onto it using the drawImage API. To prevent the rotation operation impacting other Canvas drawing operations, you can save and restore the GraphicsContext before and after performing the rotation (as it appears you are already doing from the code in your question).
However, one way to accomplish what you wish without rotating the GraphicsContext is to use a SceneGraph in combination with a Canvas. Place the Image in a ImageView, apply a rotate transform to the image, snapshot it to get a rotated image, then draw the rotated image into your Canvas.
ImageView iv = new ImageView(image);
iv.setRotate(40);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
Image rotatedImage = iv.snapshot(params, null);
gc.drawImage(rotatedImage, 0, 0);
Sample code:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.*;
import javafx.scene.image.*;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/** Rotates and places it in a canvas */
public class RotatedImageInCanvas extends Application {
@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();
ImageView iv = new ImageView(image);
iv.setRotate(40);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
Image rotatedImage = iv.snapshot(params, null);
gc.drawImage(rotatedImage, 0, 0);
// 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); }
}
Normally, I would not recommend mixing scene graph and canvas APIs as done in the above sample, but instead just code to only the scene graph API or only the canvas API.
For a sample of a canvas only solution, see the answer to:
In general, for most operations, I find working with the Scene Graph API simpler than coding to the Canvas API and recommend using the Scene Graph API rather than the Canvas API for most tasks.