如何使用Javafx Canvas绘制1像素线? [英] How to draw an 1 pixel line using Javafx Canvas?

查看:617
本文介绍了如何使用Javafx Canvas绘制1像素线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在谷歌搜索,发现一些相关的问题/帖子,但没有解决我的问题。

I've been googling and searching, found some some related questions/posts but none of the address my problem.

我在画布上直接绘制线条(JavaFX )使用:

I am drawing lines directly on canvas (JavaFX) using:

gc.setStroke(color);
gc.setLineWidth(lineWidth);
gc.strokeLine(startX, startY, endX, endY);

我想要1像素宽的线条。所以我设置lineWidth = 1。
我得到这个:

I want 1 pixel width lines. So I set lineWidth=1. I get this:

请注意,线条模糊不清。它不是1个像素。
我试图将lineWidth设置为0.1或0.01,等等。它不会改变结果。

Note that the lines are blurred. It is not 1 pixel. I've tried to set lineWidth to 0.1 or 0.01, etc. It does not change the result.

顺便说一句......我不明白为什么这个参数是双精度的。我在某处读到它与DPI有关。但我不明白单位是什么以及如何将其转换为像素。
Oracle的文档没有帮助。 (或者我没有找到有帮助的那个)

By the way... I do not understand why this parameter is a double. I read somewhere that it has to do with DPI. But I do not understand what is the unit and how it is converted to pixels. Oracle's documentation does not help. (or I did not find the one that helps)

我想改为:

这是在另一个实施的平台。请注意,线条很清晰,只有一个像素。

This was implemented in another platform. Note that lines are sharp and have just one 1 pixel.

推荐答案

想象一下,每个像素都是一个(小)矩形(而不是一个)点)。整数坐标是像素之间的边界;所以带有整数坐标的(水平或垂直)线落在像素之间。这是通过抗锯齿渲染的,近似于一个像素的一半线而另一个像素的一半。向左或向右移动0.5像素的线将其移动到像素的中心,绕过问题。

Imagine each pixel as a (small) rectangle (instead of a point). The integer coordinates are the boundaries between pixels; so a (horizontal or vertical) line with integer coordinates falls "between pixels". This is rendered via antialising, approximating half of the line on one pixel and half on the other. Moving the line 0.5 pixels left or right moves it to the center of the pixel, getting around the issue.

以下是一个示例:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SharpCanvasTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        Canvas sharpCanvas = createCanvasGrid(600, 300, true);
        Canvas blurryCanvas = createCanvasGrid(600, 300, false);
        VBox root = new VBox(5, sharpCanvas, blurryCanvas);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

    private Canvas createCanvasGrid(int width, int height, boolean sharp) {
        Canvas canvas = new Canvas(width, height);
        GraphicsContext gc = canvas.getGraphicsContext2D() ;
        gc.setLineWidth(1.0);
        for (int x = 0; x < width; x+=10) {
            double x1 ;
            if (sharp) {
                x1 = x + 0.5 ;
            } else {
                x1 = x ;
            }
            gc.moveTo(x1, 0);
            gc.lineTo(x1, height);
            gc.stroke();
        }

        for (int y = 0; y < height; y+=10) {
            double y1 ;
            if (sharp) {
                y1 = y + 0.5 ;
            } else {
                y1 = y ;
            }
            gc.moveTo(0, y1);
            gc.lineTo(width, y1);
            gc.stroke();
        }
        return canvas ;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

结果:

这篇关于如何使用Javafx Canvas绘制1像素线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆