HMCL
HMCL copied to clipboard
[Feature] 添加截图功能
概述 | Summary
用户按下 F2 后,使用当前时间等信息作为截图文件名称并保存在指定的截图目录下。
该功能使用频率可能不高因此可默认禁用,并在设置中启用后 F2 才生效。
原因 | Reason
使用第三方截图工具截取 HMCL 时,可能会出现截图尺寸比窗口略大,从而导致截图中包含额外的背景内容。
支持截图后,生成的图片可用于问题反馈及文档截图。
详情 | Description
添加全局 F2 监听事件,事件触发后获取所有 Window 对象,根据该对象获取其位置坐标及使用透明背景填充的截图,然后将所有截图根据位置关系合成为一张图片。
// press F2 to take a screenshot
navigator.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() != KeyCode.F2) return;
SnapshotParameters transparentParams = new SnapshotParameters();
transparentParams.setFill(Color.TRANSPARENT);
record Shot(BufferedImage img, double x, double y) {
}
List<Shot> shots = new ArrayList<>();
for (Window window : Window.getWindows()) {
if (!window.isShowing() || window.getScene() == null || window.getScene().getRoot() == null) continue;
WritableImage snapshot = window.getScene().getRoot().snapshot(transparentParams, null);
BufferedImage image = SwingFXUtils.fromFXImage(snapshot, null);
if (image != null) {
shots.add(new Shot(image, window.getX(), window.getY()));
}
}
if (shots.isEmpty()) return;
double minX = shots.stream().mapToDouble(shot -> shot.x).min().orElse(0);
double minY = shots.stream().mapToDouble(shot -> shot.y).min().orElse(0);
double maxX = shots.stream().mapToDouble(shot -> shot.x + shot.img.getWidth()).max().orElse(0);
double maxY = shots.stream().mapToDouble(shot -> shot.y + shot.img.getHeight()).max().orElse(0);
int width = (int)(maxX - minX);
int height = (int)(maxY - minY);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
shots.forEach(shot -> graphics.drawImage(shot.img, (int)(shot.x - minX), (int)(shot.y - minY), null));
graphics.dispose();
try {
ImageIO.write(image, "png", new File("out.png"));
} catch (IOException ignored) {
}
});
截图效果
窗户边框是HMCL自行绘制的,对操作系统而言这一圈阴影就是窗口的内容,个人感觉没啥必要 在macOS弹出文件选择器的时候会给窗口加遮罩,也可以看出来这个问题
https://github.com/HMCL-dev/HMCL/issues/2081