javafx - 在 JavaFX 中自动裁剪图像
问题描述
我有一个程序,它通过一个可视化几个图像ImageView
,这些图像从大约 32x32 像素适合 55x55 像素的大小。不幸的是,所有图像都有透明背景的“边框”,因此图像之间会出现间隙。有没有办法在 javaFX 中裁剪图像,使其还原为实际图片?
例子:
想要的外观(用手严重裁剪)
实际外观
解决方案
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();
}
推荐阅读
- json - 如何从flutter中的单个json获取键列表和值列表
- memory-management - Redis 集群是否有可能拥有超过 256TB 的容量?
- r - 无法为签名“RasterLayer”找到函数“gui”的继承方法
- mysql - 如何根据另一列的特定列值过滤表?
- android-studio - 在“PATH”中找不到可执行文件。请确保已安装 Gauge。即使它安装在 windows 和 mac
- powerapps-canvas - 在列表 B 列 2 的值中筛选 SharePoint 列表 A 列 1 的值,而没有删除警告
- spring-boot - GraphQL + SpringBoot:如何在响应中隐藏请求中的某些字段
- c++ - Using the Clipboard in Win32
- javascript - React / JS Uncaught ReferenceError:未定义要求
- java - Spring Boot QueryDsl java.lang.UnsupportedOperationException