我试图了解JavaFX canvas setStroke方法的工作方式。它不会将像素的颜色设置为所需的值。 但是setFill方法没问题。
Canvas canvas = new Canvas(500, 500);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.RED);
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
int x = 10;
int y = 10;
printPixelRGB(x, y); // displays: red=255, green=0, blue=0 -> OK
// scenario 1: using fill-methods
gc.setStroke(Color.WHITE);
gc.strokeRect(x, y, 200, 200);
printPixelRGB(x, y); // displays: red=255, green=191, blue=191 -> ????
// scenario 2: using stroke-methods
gc.setFill(Color.WHITE);
gc.fillRect(x, y, 200, 200);
printPixelRGB(x, y); // displays: red=255, green=255, blue=255 -> OK
private void printPixelRGB(int x, int y) {
WritableImage snap = gc.getCanvas().snapshot(null, null);
int color = snap.getPixelReader().getArgb(x, y);
int red = (color >> 16) & 0xff;
int green = (color >> 8) & 0xff;
int blue = color & 0xff;
System.out.printf("red=%-3d, green=%-3d, blue=%-3d \n", red, green, blue);
} // printPixelRGB()
方案2的结果符合预期。 另一方面,场景1的结果很奇怪:像素不是完全白色!怎么会来?
我该如何解决?
谢谢
答案 0 :(得分:2)
这是抗锯齿的效果。
该像素没有被线条100%覆盖。因此,结果颜色将在绘制操作之前的像素颜色和笔触颜色之间进行插值。
以下代码可让您观察效果:
@Override
public void start(Stage primaryStage) {
Canvas canvas = new Canvas(800, 300);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.RED);
gc.fillRect(0, 0, 800, 300);
gc.setStroke(Color.WHITE);
final double dx = 0;
for (double x = 10, s = 1; x < (800 - 40); s++, x += 50) {
gc.setLineWidth(s);
gc.strokeLine(x + dx, 0, x + dx, 300);
}
WritableImage snap = canvas.snapshot(null, null);
PixelReader reader = snap.getPixelReader();
for (int x = 10; x < (800 - 40); x += 50) {
Color color = reader.getColor(x, 150);
System.out.printf("red=%-3d, green=%-3d, blue=%-3d\n", (int) (color.getRed() * 0xFF),
(int) (color.getGreen() * 0xFF), (int) (color.getBlue() * 0xFF));
}
primaryStage.setScene(new Scene(new StackPane(canvas)));
primaryStage.show();
}
绘制的第一行覆盖[10-lineWidth/2, 10+lineWidth/2] = [9.5, 10.5]
的x间隔。索引为10的列仅覆盖了一半,这就是为什么生成的颜色为((255, 0, 0) + (255, 255, 255)) / 2 = (255, 127, 127)
(已经四舍五入为整数值)的原因
修改dx
以完全覆盖该列,您将获得笔触颜色:
final double dx = 0.5;
您在代码中填充的矩形完全覆盖了像素,因此将颜色设置为填充颜色。将0.5
添加到您填充的矩形的一个起始坐标中,您将观察到与笔触相似的效果。