为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕尼黑的夜晚无繁华 2022-05-25 17:44:44
我试图了解 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-methodsgc.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  -> OKprivate 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 的结果很奇怪:像素不是全白的!!怎么会?我怎样才能解决这个问题?
查看完整描述

1 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

这就是抗锯齿的效果。


像素不是 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();

}

绘制的第一条线覆盖 的 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到您填充的矩形的起始坐标之一,您将观察到与笔划类似的效果。


查看完整回答
反对 回复 2022-05-25
  • 1 回答
  • 0 关注
  • 264 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信