JavaFX 中 TilePane 中的字母可视化

Letter visualisation in TilePane in JavaFX

我需要做的事情:

我正在尝试编写一些代码来可视化任何字符的每个像素。我决定最好的方法是在 Tile Pane 中将像素显示为矩形。所以这是我需要达到的效果:

我的问题是什么:

我写了一些代码来获取 text1 的 snaphost 并将其保存为 WritableImage。然后我使用 PixelReader 通过 argb 方法读取该图像的每个像素。在循环中,当每个整数 rgb 值大于 TRESHOLD(更亮)时,我添加带有白色背景的新图块。除非我添加黑色背景的瓷砖。但是我的想法仍然有问题,我得到了这个效果:

有我的代码:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        //Create single letter string
        String letter = "a";
        //Create new text
        Text text1 = new Text(letter);
        //Set font for text
        text1.setFont(Font.font("Calibri", FontWeight.NORMAL, 12));

        //Save text1 as writable image
        WritableImage newImg = text1.snapshot(null, null);

        //Take bounds of letter
        int imgHeight = (int) newImg.getHeight();
        int imgWidth = (int) newImg.getWidth();

        //Create pixel reader from newImg
        PixelReader reader = newImg.getPixelReader();

        //This is for preview image
        ImageView imgPreview = new ImageView(newImg);

        //Create tilePane
        TilePane tilePane = new TilePane();
        //New group with tilePane inside
        Group display = new Group(tilePane);

        //Bg color
        tilePane.setStyle("-fx-background-color: gray;");
        //Small gaps between tiles
        tilePane.setHgap(2);
        tilePane.setVgap(2);

        //Set quantity of columns equals image width
        tilePane.setPrefColumns(imgWidth);
        //Set quantity of rows equals image height
        tilePane.setPrefRows(imgHeight );

        //Here I set tolerance treshold
        int TOLERANCE_THRESHOLD = 0xf0;


        for (int x = 0; x < imgWidth; x++) {
            for (int y = 0; y < imgHeight; y++) {

                int argb = reader.getArgb(x, y);

                int r = (argb >> 16) & 0xFF;
                int g = (argb >> 8) & 0xFF;
                int b = argb & 0xFF;

                if (r >= TOLERANCE_THRESHOLD
                        && g >= TOLERANCE_THRESHOLD
                        && b >= TOLERANCE_THRESHOLD) {
                    tilePane.getChildren().add(createElement(Color.WHITE));
                }
                else tilePane.getChildren().add(createElement(Color.BLACK));

            }
        }

        // Create new stage
        Stage stage = new Stage();
        //Create new group
        Group grupa = new Group();
        Scene scene = new Scene(grupa, 400, 300, Color.GRAY);

        grupa.getChildren().addAll(display);
        stage.setScene(scene);
        stage.show();
    }

    private Rectangle createElement(Color color) {
        Rectangle rectangle = new Rectangle(15, 15);
        //rectangle.setStroke(Color.ORANGE);
        rectangle.setFill(color);

        return rectangle;
    }

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

我做错了什么?也许还有其他方法可以达到这种效果?

你的外循环变量是x坐标,内循环变量是y坐标。

这意味着您从左到右逐列读取像素。 TilePane 但是要求子列表从上到下逐行排序。

要解决此问题,只需交换循环即可。使用:

for (int y = 0; y < imgHeight; y++) {
    for (int x = 0; x < imgWidth; x++) {
        ...
    }
}

而不是

for (int x = 0; x < imgWidth; x++) {
    for (int y = 0; y < imgHeight; y++) {
        ...
    }
}