猿问

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

我试图了解 JavaFX 画布 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 的结果很奇怪:像素不是全白的!!怎么会?


我怎样才能解决这个问题?


慕尼黑的夜晚无繁华
浏览 265回答 1
1回答

开心每一天1111

这就是抗锯齿的效果。像素不是 100% 被线覆盖。因此,生成的颜色在绘制操作之前的像素颜色和笔触颜色之间进行插值。下面的代码可以让你观察效果:@Overridepublic void start(Stage primaryStage) {&nbsp; &nbsp; Canvas canvas = new Canvas(800, 300);&nbsp; &nbsp; GraphicsContext gc = canvas.getGraphicsContext2D();&nbsp; &nbsp; gc.setFill(Color.RED);&nbsp; &nbsp; gc.fillRect(0, 0, 800, 300);&nbsp; &nbsp; gc.setStroke(Color.WHITE);&nbsp; &nbsp; final double dx = 0;&nbsp; &nbsp; for (double x = 10, s = 1; x < (800 - 40); s++, x += 50) {&nbsp; &nbsp; &nbsp; &nbsp; gc.setLineWidth(s);&nbsp; &nbsp; &nbsp; &nbsp; gc.strokeLine(x + dx, 0, x + dx, 300);&nbsp; &nbsp; }&nbsp; &nbsp; WritableImage snap = canvas.snapshot(null, null);&nbsp; &nbsp; PixelReader reader = snap.getPixelReader();&nbsp; &nbsp; for (int x = 10; x < (800 - 40); x += 50) {&nbsp; &nbsp; &nbsp; &nbsp; Color color = reader.getColor(x, 150);&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("red=%-3d, green=%-3d, blue=%-3d\n", (int) (color.getRed() * 0xFF),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (int) (color.getGreen() * 0xFF), (int) (color.getBlue() * 0xFF));&nbsp; &nbsp; }&nbsp; &nbsp; primaryStage.setScene(new Scene(new StackPane(canvas)));&nbsp; &nbsp; primaryStage.show();}绘制的第一条线覆盖 的 x 区间[10-lineWidth/2, 10+lineWidth/2] = [9.5, 10.5]。索引为 10 的列仅覆盖了一半,这就是结果颜色为((255, 0, 0) + (255, 255, 255)) / 2 = (255, 127, 127)(已四舍五入为整数值)的原因修改dx以完全覆盖该列,您将获得描边颜色:final double dx = 0.5;像素被您在代码中填写的矩形完全覆盖,因此颜色设置为填充颜色。添加0.5到您填充的矩形的起始坐标之一,您将观察到与笔划类似的效果。
随时随地看视频慕课网APP

相关分类

Java
我要回答