JavaFX drawImage 旋转
JavaFX drawImage rotated
我正在玩 JavaFX,在 class start(Stage theStage) 中我有以下代码:
/*... Scene, stage, canvas ...*/
GraphicsContext gc = canvas.getGraphicsContext2D();
Image imgage = new Image("gfx/image.png");
gc.drawImage(image, 256, 256);
如何在不旋转轴的情况下旋转绘制它?我发现并尝试了这个:
gc.save(); // saves the current state on stack, including the current transform
gc.rotate(45);
gc.drawImage(image);
gc.restore();
然而,它也改变了轴,当我使用改变位置 x 和 y 移动图像时......它出错了,因为它也使轴旋转。我一直在考虑使用 sin 和 cos 函数重新计算运动,但我确信有更简单的解决方案。
它可能与 BufferedImage 一起工作,但他们使用不同的图形绘制它class,我不知道如何让它一起工作。
编辑:好的,如何只旋转图像而不旋转整个 GraphicsContext?
已解决:
谢谢大家的帮助:))我已经用这个解决了这个问题 >>
ImageView iv = new ImageView(new Image( "gfx/earth.png"));
iv.setRotate(40);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
Image rotatedImage = iv.snapshot(params, null);
gc.drawImage(rotatedImage, 0, 0);
让我们看看我是否能够理解你的问题...
how to rotate Image only without rotating the whole GraphicsContext?
您不能只使用 GraphicsContext 来做到这一点。您需要旋转 GraphicsContext 以使用 drawImage API 将旋转图像渲染到其上。为防止旋转操作影响其他 Canvas 绘图操作,您可以在执行旋转之前和之后保存和恢复 GraphicsContext(看起来您已经从问题中的代码中这样做了)。
但是,在不旋转 GraphicsContext 的情况下实现您希望的一种方法是将 SceneGraph 与 Canvas 结合使用。将图像放在 ImageView 中,对图像应用旋转变换,对其快照以获得旋转图像,然后将旋转图像绘制到您的 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);
示例代码:
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); }
}
通常,我不建议像上面的示例那样混合场景图和 canvas API,而是只对场景图 API 或仅对canvas API.
有关 canvas 解决方案的示例,请参阅以下问题的答案:
- How to draw image rotated on JavaFX Canvas?
一般来说,对于大多数操作,我发现使用场景图 API 比编码到 Canvas API 更简单,建议使用场景图 API而不是大多数任务的 Canvas API。
根据其他评论,如果您想围绕一个点旋转图像并且不想更改图像的中心,您应该像我在 rotateImage 函数中所做的那样添加 setViewport 和 setTransform。
public Image rotateImage(Image image, int rotation) {
ImageView iv = new ImageView(image);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
params.setTransform(new Rotate(rotation, image.getHeight() / 2, image.getWidth() / 2));
params.setViewport(new Rectangle2D(0, 0, image.getHeight(), image.getWidth()));
return iv.snapshot(params, null);
}
一种相当快捷但也有效的方法是平移和旋转整个 GraphicsContext,然后相对于 0 绘制图像(在这种情况下,旋转是从图像的中间开始的)。然后,绘制完图像后,反转动作。
例如,如果您有图像 (img)、GraphicsContext (gc) 和图像位置 (xp, yp),则:
// Translate and rotate.
gc.translate(xp, yp);
gc.rotate(degrees);
// Note how the image is drawn relative to 0. Since the image needs to be
// rotated around the image center, the center is simply half of the image
// dimension.
gc.drawImage( image, -image.getWidth/2.0, -image.getImageHeight/2.0);
// Reverse the translation and rotation once drawn.
gc.rotate(-degrees);
gc.translate(-xp, -yp);
我正在玩 JavaFX,在 class start(Stage theStage) 中我有以下代码:
/*... Scene, stage, canvas ...*/
GraphicsContext gc = canvas.getGraphicsContext2D();
Image imgage = new Image("gfx/image.png");
gc.drawImage(image, 256, 256);
如何在不旋转轴的情况下旋转绘制它?我发现并尝试了这个:
gc.save(); // saves the current state on stack, including the current transform
gc.rotate(45);
gc.drawImage(image);
gc.restore();
然而,它也改变了轴,当我使用改变位置 x 和 y 移动图像时......它出错了,因为它也使轴旋转。我一直在考虑使用 sin 和 cos 函数重新计算运动,但我确信有更简单的解决方案。
它可能与 BufferedImage 一起工作,但他们使用不同的图形绘制它class,我不知道如何让它一起工作。
编辑:好的,如何只旋转图像而不旋转整个 GraphicsContext?
已解决: 谢谢大家的帮助:))我已经用这个解决了这个问题 >>
ImageView iv = new ImageView(new Image( "gfx/earth.png"));
iv.setRotate(40);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
Image rotatedImage = iv.snapshot(params, null);
gc.drawImage(rotatedImage, 0, 0);
让我们看看我是否能够理解你的问题...
how to rotate Image only without rotating the whole GraphicsContext?
您不能只使用 GraphicsContext 来做到这一点。您需要旋转 GraphicsContext 以使用 drawImage API 将旋转图像渲染到其上。为防止旋转操作影响其他 Canvas 绘图操作,您可以在执行旋转之前和之后保存和恢复 GraphicsContext(看起来您已经从问题中的代码中这样做了)。
但是,在不旋转 GraphicsContext 的情况下实现您希望的一种方法是将 SceneGraph 与 Canvas 结合使用。将图像放在 ImageView 中,对图像应用旋转变换,对其快照以获得旋转图像,然后将旋转图像绘制到您的 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);
示例代码:
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); }
}
通常,我不建议像上面的示例那样混合场景图和 canvas API,而是只对场景图 API 或仅对canvas API.
有关 canvas 解决方案的示例,请参阅以下问题的答案:
- How to draw image rotated on JavaFX Canvas?
一般来说,对于大多数操作,我发现使用场景图 API 比编码到 Canvas API 更简单,建议使用场景图 API而不是大多数任务的 Canvas API。
根据其他评论,如果您想围绕一个点旋转图像并且不想更改图像的中心,您应该像我在 rotateImage 函数中所做的那样添加 setViewport 和 setTransform。
public Image rotateImage(Image image, int rotation) {
ImageView iv = new ImageView(image);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
params.setTransform(new Rotate(rotation, image.getHeight() / 2, image.getWidth() / 2));
params.setViewport(new Rectangle2D(0, 0, image.getHeight(), image.getWidth()));
return iv.snapshot(params, null);
}
一种相当快捷但也有效的方法是平移和旋转整个 GraphicsContext,然后相对于 0 绘制图像(在这种情况下,旋转是从图像的中间开始的)。然后,绘制完图像后,反转动作。
例如,如果您有图像 (img)、GraphicsContext (gc) 和图像位置 (xp, yp),则:
// Translate and rotate.
gc.translate(xp, yp);
gc.rotate(degrees);
// Note how the image is drawn relative to 0. Since the image needs to be
// rotated around the image center, the center is simply half of the image
// dimension.
gc.drawImage( image, -image.getWidth/2.0, -image.getImageHeight/2.0);
// Reverse the translation and rotation once drawn.
gc.rotate(-degrees);
gc.translate(-xp, -yp);