在JavaFX中自动裁剪图像

时间:2019-08-13 22:06:40

标签: javafx

我有一个程序,可以通过ImageView可视化多个图像,这些图像的大小从大约32x32像素增加到55x55像素。 不幸的是,所有图像都具有透明背景的“边框”,因此图像之间显示有间隙。 有没有一种方法可以在javaFX中裁剪图像,使其缩小为实际图片?

示例:

所需的外观(手工裁剪很差)

enter image description here

实际外观

enter image description here

1 个答案:

答案 0 :(得分:2)

Afaik没有为此提供内置方法。正如@Slaw在他的评论中提到的那样,您需要使用PixelReader来检查空的行/列。根据该信息,您可以为viewport设置ImageView属性:

@Override
public void start(Stage primaryStage) {
    // using stackoverflow logo, since your image is completely opaque
    Image image = new Image("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png");
    ImageView imageView = new ImageView(image);

    int w = (int) image.getWidth();
    int h = (int) image.getHeight();

    int firstNonEmptyColumn = 0;
    int firstNonEmptyRow = 0;
    int lastNonEmptyColumn = w - 1;
    int lastNonEmptyRow = h - 1;

    PixelReader reader = image.getPixelReader();

    outer: for (; firstNonEmptyColumn < w; firstNonEmptyColumn++) {
        for (int y = 0; y < h; y++) {
            // stop, if most significant byte (alpha channel) is != 0
            if ((reader.getArgb(firstNonEmptyColumn, y) & 0xFF000000) != 0) {
                break outer;
            }
        }
    }

    if (firstNonEmptyColumn == w) {
        imageView.setImage(null); // image completely transparent
    } else {
        outer: for (; lastNonEmptyColumn > firstNonEmptyColumn; lastNonEmptyColumn--) {
            for (int y = 0; y < h; y++) {
                if ((reader.getArgb(lastNonEmptyColumn, y) & 0xFF000000) != 0) {
                    break outer;
                }
            }
        }

        outer: for (; firstNonEmptyRow < h; firstNonEmptyRow++) {
            // use info for columns to reduce the amount of pixels that need checking
            for (int x = firstNonEmptyColumn; x <= lastNonEmptyColumn; x++) {
                if ((reader.getArgb(x, firstNonEmptyRow) & 0xFF000000) != 0) {
                    break outer;
                }
            }
        }

        outer: for (; lastNonEmptyRow > firstNonEmptyRow; lastNonEmptyRow--) {
            for (int x = firstNonEmptyColumn; x <= lastNonEmptyColumn; x++) {
                if ((reader.getArgb(x, lastNonEmptyRow) & 0xFF000000) != 0) {
                    break outer;
                }
            }
        }

        // set viewport to only show the opaque parts
        imageView.setViewport(new Rectangle2D(
                firstNonEmptyColumn,
                firstNonEmptyRow,
                lastNonEmptyColumn - firstNonEmptyColumn + 1,
                lastNonEmptyRow - firstNonEmptyRow + 1));

    }

    // visualize image bounds
    Rectangle rect = new Rectangle(imageView.prefWidth(-1), imageView.prefHeight(-1), Color.LIGHTGREEN);

    StackPane root = new StackPane(rect, imageView);
    root.setStyle("-fx-background-color:blue");


    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.show();
}
相关问题