Статьи

JavaFX Tip 2: Sharp Drawing с Canvas API

Когда я впервые начал работать с Canvas API, я заметил, что результаты моего кода рендеринга были несколько размытыми и, что еще хуже, противоречивыми. Некоторые линии были размытыми, другие резкими. Исходя из Swing, мне потребовалось некоторое время, чтобы понять, что это было вызвано системой координат JavaFX, которая позволяет выполнять рендеринг с двойной точностью.
Для решения этой проблемы все, что нужно, это использовать координаты «посередине». Итак, в моем коде вы теперь найдете много методов, называемых snapXZY () (похожие методы можно найти в самом коде JavaFX), которые сначала приводят данную координату к целому числу, а затем добавляют к нему .5. Следующий скриншот показывает разницу при использовании этого подхода.

bildschirmfoto-2014-04-10-эм-11-59-49
Код ниже был использован для этого примера:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
 
/**
 * Tip 2: How to render sharp lines in a canvas.
 */
public class Tip2DrawingSharpLinesInCanvas extends
        Application {
 
    class MyCanvas extends Canvas {
 
        public MyCanvas(boolean drawSharpLines) {
 
            setWidth(150);
            setHeight(150);
 
            double w = getWidth();
            double h = getHeight();
 
            GraphicsContext gc = getGraphicsContext2D();
            gc.clearRect(0, 0, w, h);
 
            gc.setStroke(Color.GRAY);
            gc.strokeRect(0, 0, w, h);
 
            for (double y = 20; y <= h - 20; y += 10) {
                if (drawSharpLines) {
                    // Snap the y coordinate
                    gc.strokeLine(10,
                                   snap(y),
                                   w - 10,
                                   snap(y));
                } else {
                    gc.strokeLine(10, y, w - 10, y);
                }
            }
        }
 
        private double snap(double y) {
            return ((int) y) + .5;
        }
    }
 
    @Override
    public void start(Stage stage) throws Exception {
        MyCanvas canvasBlurry = new MyCanvas(false);
        MyCanvas canvasSharp = new MyCanvas(true);
 
        Label labelBlurry = new Label("Blurry");
        Label labelSharp = new Label("Sharp");
 
        VBox.setMargin(canvasBlurry, new Insets(10));
        VBox.setMargin(canvasSharp, new Insets(10));
 
        VBox.setMargin(labelBlurry,
                     new Insets(10, 10, 0, 10));
        VBox.setMargin(labelSharp,
                     new Insets(10, 10, 0, 10));
 
        VBox box = new VBox();
        box.getChildren().add(labelBlurry);
        box.getChildren().add(canvasBlurry);
        box.getChildren().add(labelSharp);
        box.getChildren().add(canvasSharp);
 
        stage.setScene(new Scene(box));
        stage.setTitle("Tip 2: Sharp Lines in Canvas");
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}
Ссылка: JavaFX Tip 2: Sharp Drawing с Canvas API от нашего партнера JCG Дирка Леммермана в блоге Pixel Perfect .