JavaFX 拉伸 Canvas 到维度
JavaFX Stretch Canvas To Dimensions
在我的 C++ Windows 程序中,我直接绘制到固定像素缓冲区 (u32 *
) 并拉伸它以适应 window 尺寸:
StretchDIBits(device_context,
0, 0, window_width, window_height,
src_x, src_y, src_width, src_height,
src_memory, src_info,
DIB_RGB_COLORS, SRCCOPY);
我是 JavaFX 的新手。
在 JavaFX 中说我有:
@Override
public void
start(Stage primary_stage) throws Exception
{
Group root = new Group();
Scene scene = new Scene(root);
primary_stage.setScene(scene);
Canvas canvas = new Canvas(1280, 720);
root.getChildren().add(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
}
我想在 Windows 示例中将 canvas(它是 GraphicsContext
)视为固定大小的像素缓冲区。我想将每一帧拉伸或缩小到 window 尺寸(或我指定的任何尺寸)。我看到的许多例子似乎增加了 canvas 节点本身的宽度和高度。如果有意义的话,我想拉伸 canvas 的 content,而不是 canvas 节点本身。
JavaFX 是否有等同于 StretchDIBits
的工具?
我不相信有一个内置方法可以调用来做你想做的事。但是您可以缩放 Canvas
以填充可用的 space。随着 canvas 的父项调整大小时,您需要不断更新比例因子。这可能最好通过自定义布局来实现。例如:
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Region;
public class AutoScalingCanvas extends Region {
private final Canvas canvas;
public AutoScalingCanvas(double canvasWidth, double canvasHeight) {
this.canvas = new Canvas(canvasWidth, canvasHeight);
getChildren().add(canvas);
}
public GraphicsContext getGraphicsContext2D() {
return canvas.getGraphicsContext2D();
}
@Override
protected void layoutChildren() {
double x = getInsets().getLeft();
double y = getInsets().getTop();
double w = getWidth() - getInsets().getRight() - x;
double h = getHeight() - getInsets().getBottom() - y;
// preserve aspect ratio while also staying within the available space
double sf = Math.min(w / canvas.getWidth(), h / canvas.getHeight());
canvas.setScaleX(sf);
canvas.setScaleY(sf);
positionInArea(canvas, x, y, w, h, -1, HPos.CENTER, VPos.CENTER);
}
}
下面是一个使用上面的例子:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
AutoScalingCanvas canvas = new AutoScalingCanvas(500, 300);
canvas.getGraphicsContext2D().fillOval(200, 100, 100, 100);
canvas.getGraphicsContext2D().setLineWidth(5);
canvas.getGraphicsContext2D().setStroke(Color.RED);
canvas.getGraphicsContext2D().strokeRect(0, 0, 500, 300);
primaryStage.setScene(new Scene(canvas));
primaryStage.show();
}
}
在我的 C++ Windows 程序中,我直接绘制到固定像素缓冲区 (u32 *
) 并拉伸它以适应 window 尺寸:
StretchDIBits(device_context,
0, 0, window_width, window_height,
src_x, src_y, src_width, src_height,
src_memory, src_info,
DIB_RGB_COLORS, SRCCOPY);
我是 JavaFX 的新手。 在 JavaFX 中说我有:
@Override
public void
start(Stage primary_stage) throws Exception
{
Group root = new Group();
Scene scene = new Scene(root);
primary_stage.setScene(scene);
Canvas canvas = new Canvas(1280, 720);
root.getChildren().add(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
}
我想在 Windows 示例中将 canvas(它是 GraphicsContext
)视为固定大小的像素缓冲区。我想将每一帧拉伸或缩小到 window 尺寸(或我指定的任何尺寸)。我看到的许多例子似乎增加了 canvas 节点本身的宽度和高度。如果有意义的话,我想拉伸 canvas 的 content,而不是 canvas 节点本身。
JavaFX 是否有等同于 StretchDIBits
的工具?
我不相信有一个内置方法可以调用来做你想做的事。但是您可以缩放 Canvas
以填充可用的 space。随着 canvas 的父项调整大小时,您需要不断更新比例因子。这可能最好通过自定义布局来实现。例如:
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Region;
public class AutoScalingCanvas extends Region {
private final Canvas canvas;
public AutoScalingCanvas(double canvasWidth, double canvasHeight) {
this.canvas = new Canvas(canvasWidth, canvasHeight);
getChildren().add(canvas);
}
public GraphicsContext getGraphicsContext2D() {
return canvas.getGraphicsContext2D();
}
@Override
protected void layoutChildren() {
double x = getInsets().getLeft();
double y = getInsets().getTop();
double w = getWidth() - getInsets().getRight() - x;
double h = getHeight() - getInsets().getBottom() - y;
// preserve aspect ratio while also staying within the available space
double sf = Math.min(w / canvas.getWidth(), h / canvas.getHeight());
canvas.setScaleX(sf);
canvas.setScaleY(sf);
positionInArea(canvas, x, y, w, h, -1, HPos.CENTER, VPos.CENTER);
}
}
下面是一个使用上面的例子:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
AutoScalingCanvas canvas = new AutoScalingCanvas(500, 300);
canvas.getGraphicsContext2D().fillOval(200, 100, 100, 100);
canvas.getGraphicsContext2D().setLineWidth(5);
canvas.getGraphicsContext2D().setStroke(Color.RED);
canvas.getGraphicsContext2D().strokeRect(0, 0, 500, 300);
primaryStage.setScene(new Scene(canvas));
primaryStage.show();
}
}