Just now I was facing the same issue, but I'm not loading any image, I'm taking snapshots of Nodes. So, I wanted to expand on the @jewelsea answer with my workaround specifically for this use case:
// Get the screen on which the node is displayed
public Screen getScreenFor(Node node) {
Bounds bounds = node.localToScreen(node.getLayoutBounds());
Rectangle2D toRect = new Rectangle2D(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
return Screen.getScreens().stream()
.filter(screen -> screen.getBounds().contains(toRect))
.findFirst()
.orElse(null);
}
// Node that w and h can be retrieved directly from Node, but I needed them because they may not match in my case
public WriteableImage snapshot(Node node, double w, double h, SnapshotParameters parameters) {
Screen screen = getScreenFor(node);
// Use this workaround only for HiDPI screens
if (screen.getOutputScaleX() != 1.0) {
double scale = screen.getOutputScaleX();
int scaledW = (int) (w * scale);
int scaledH = (int) (h * scale);
WriteableImage snapshot = new WriteableImage(scaledW, scaledH);
parameters.setTransform(Transform.scale(scale, scale));
node.snapshot(parameters, snapshot);
return snapshot;
}
return node.snapshot(parameters, null);
}
Edit: just a little rant, I'm quite tired of dwelling with JavaFX bs! Hope this could save someone a headache