Dre*_*een 4 java png transparency javafx image
我在渐变背景上加载并显示透明PNG,结果如下:
如果我在Paint.NET中打开相同的文件,添加它看起来像这样的背景:
不知何故,JavaFX使图像松散清晰,我担心这可能是我的应用程序中的所有图像的问题,而这只是在这种特殊情况下最明显的.
这是提取的代码,显示我如何加载此特定图像:
ImageView imgDownload = new ImageView(this.getClass().getResource("/img/docstore/document_downloaded_btn.png").toExternalForm());
imgDownload.setFitWidth(59);
imgDownload.setFitHeight(32);
GridPane.setHalignment(imgDownload, HPos.CENTER);
grid_item.add(imgDownload, 3, 0);
Run Code Online (Sandbox Code Playgroud)
作为参考,这里是原始图像的链接.
我正在寻找一个答案,强调这可能发生的原因
jew*_*sea 10
更新
Java 8中的JavaFX图像现在在所有情况下都清晰呈现.
该问题中描述的原始问题已得到解决.
Dreen提交的关于此行为的错误,RT-28765图像的不正确的子像素位置被关闭为RT-19282 [StackPane]不需要的模糊与ImageView的副本 .对于Java 8,RT-19282已关闭.
我在Windows 7上测试了Java 8 build 108.此答案中的示例应用程序现在可以正确显示(没有模糊图像有时会在x或y方向偏移半个像素).
这是一个很好的问题和非常好奇的行为.
我整理了一个示例程序,它提供了可能的解释和解决方法.
运行它并稍微拖动边框以调整其大小后,此程序的输出如下所示.左边的模糊云是ImageView
放在一个标准中的标准GridPane
.右边的清晰云是一个ImageView
包含在我的解决方法修复类(CenteredRegion
)中,放在同一个GridPane
.
显示上面的图像时,程序的输出是:
Layout SnapToPixel: true
...
fuzzy: New Bounds: BoundingBox [minX:14.5, minY:12.5, minZ:0.0, width:59.0, height:32.0, depth:0.0, maxX:73.5, maxY:44.5, maxZ:0.0]
fuzzy: xDisplacement: 0.5, yDisplacement: 0.5
crisp: New Bounds: BoundingBox [minX:84.0, minY:13.0, minZ:0.0, width:59.0, height:32.0, depth:0.0, maxX:143.0, maxY:45.0, maxZ:0.0]
crisp: xDisplacement: 0.0, yDisplacement: 0.0
Run Code Online (Sandbox Code Playgroud)
如您所见,模糊图像没有像素对齐,并且在x和y方向上偏移了半个像素,导致它看起来模糊.尽管网格区域snapToPixel
设置为true
.
当包含布局的舞台被动态调整大小时,模糊图像将在像素对齐和不像素对齐之间交替(取决于场景的宽度和高度的奇怪或均匀性).由于模糊图像在模糊和清晰之间连续交替,因此在调整舞台边框大小时会产生令人讨厌的闪烁效果.
snapToPixel
在父容器上设置为true 时,模糊图像的行为似乎是一个错误,所以我建议在JavaFX运行时项目中提交一个错误并链接回bug中的堆栈溢出问题并放置一个链接在评论中创建的bug.
清晰版本保持清晰,因为它位于自定义区域实现中,可确保像素对齐.
测试系统是win7 + jdk8b77 + ATI HD4600显卡.
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.value.*;
import javafx.geometry.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import static javafx.scene.layout.Region.USE_PREF_SIZE;
import javafx.stage.Stage;
public class TransparentPngSample extends Application {
public static final String IMAGE_LOC = "http://i.imgur.com/byY8whh.png";
@Override public void start(Stage stage) {
Pane layout = createSceneContent();
stage.setScene(new Scene(layout));
stage.show();
System.out.println("Layout SnapToPixel: " + layout.snapToPixelProperty().get());
}
private Pane createSceneContent() {
final Image cloudImage = new Image(IMAGE_LOC);
final ImageView fuzzyCloud = new ImageView(cloudImage);
final CenteredRegion crispCloud = new CenteredRegion(new ImageView(cloudImage));
GridPane layout = new GridPane();
layout.setHgap(10);
layout.setVgap(10);
layout.addRow(0, fuzzyCloud, crispCloud);
layout.setAlignment(Pos.CENTER);
layout.setStyle("-fx-padding: 10px; -fx-background-color: slategrey;");
fuzzyCloud.boundsInParentProperty().addListener(new BoundsReporter("fuzzy"));
crispCloud.boundsInParentProperty().addListener(new BoundsReporter("crisp"));
return layout;
}
class CenteredRegion extends Region {
private Node content;
CenteredRegion(Node content) {
this.content = content;
getChildren().add(content);
}
@Override protected void layoutChildren() {
content.relocate(
Math.round(getWidth() / 2 - content.prefWidth(USE_PREF_SIZE) / 2),
Math.round(getHeight() / 2 - content.prefHeight(USE_PREF_SIZE) / 2)
);
System.out.println("crisp content relocated to: " +
getLayoutX() + "," + getLayoutY()
);
}
public Node getContent() {
return content;
}
}
class BoundsReporter implements ChangeListener<Bounds> {
final String logPrefix;
BoundsReporter(String logPrefix) {
this.logPrefix = logPrefix;
}
@Override public void changed(ObservableValue<? extends Bounds> ov, Bounds oldBounds, Bounds newBounds) {
System.out.println(logPrefix + ": " +
"New Bounds: " + newBounds
);
double xDisplacement = newBounds.getMinX() - Math.floor(newBounds.getMinX());
double yDisplacement = newBounds.getMinY() - Math.floor(newBounds.getMinY());
System.out.println(logPrefix + ": " +
"xDisplacement: " + xDisplacement + ", " +
"yDisplacement: " + yDisplacement
);
}
}
public static void main(String[] args) { launch(args); }
}
Run Code Online (Sandbox Code Playgroud)