gpt4 book ai didi

java - setStroke() 和 setFill() 产生不同的像素颜色

转载 作者:行者123 更新时间:2023-12-02 01:41:12 24 4
gpt4 key购买 nike

我试图了解 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 的结果非常奇怪:像素不是完全白色!怎么会这样?

我该如何解决这个问题?

谢谢

最佳答案

这就是抗锯齿的效果。

像素未 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 添加到您填充的矩形的起始坐标之一,您将观察到与笔划类似的效果。

关于java - setStroke() 和 setFill() 产生不同的像素颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54437985/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com