Letter visualisation in TilePane in JavaFX

随声附和 提交于 2019-12-08 03:13:48

问题


What I need to do:

I trying to write some code for visualise every pixel of any character. I decided best way for it will be show pixels as rectangle in Tile Pane. So this is effect which i need to reach:

What's my problem:

I wrote some code to make it by take snaphost of text1 and save it as WritableImage. Then i use PixelReader for read each pixel of this image by argb method. In loop when each integer rgb value is greater than TRESHOLD (is brighter) I add new tile with white background. Unless I add tile with black background. But something is still wrong with my idea and I get this effect:

There is my code:

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);
    }
}

What I doing wrong? Maby are other ways to take this effect?


回答1:


Your outer loop variable is the x-coordinate and the inner loop variable is the y-coordinate.

This means you read the pixels column by column left to right. TilePane however requires the children list to be ordered row by row from top to bottom.

To fix the issue simply swap the loops. Use:

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

Instead of

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


来源:https://stackoverflow.com/questions/40745356/letter-visualisation-in-tilepane-in-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!