JavaFX 截图软件详细设计:功能、技术和实现
一、需求分析 在日常中,截图软件是我们常用的工具之一,因此设计一款截图软件非常有必要。本软件需要满足以下需求:
- 支持全屏截图、任意区域截图、窗口截图等多种截图模式;
- 支持对截图进行编辑,包括画笔、橡皮擦、文字、箭头等工具;
- 支持保存截图为常见图片格式(png、jpg等);
- 支持将截图复制到剪贴板;
- 界面简洁美观,易于操作。
二、技术选型
- 语言:使用 Java 语言进行开发;
- GUI 框架:使用 JavaFX 作为 GUI 框架;
- 图像处理:使用 JavaFX 提供的 Image 类进行图像处理。
三、详细设计
- 主界面设计
主界面设计如下图所示:

主界面由菜单栏、工具栏和画布组成。菜单栏包括文件、编辑和帮助三个菜单。工具栏包括全屏截图、任意区域截图、窗口截图、画笔、橡皮擦、文字、箭头、保存和复制等工具。画布用于显示截图。
- 截图功能设计 截图功能是本软件的核心功能,包括全屏截图、任意区域截图和窗口截图三种模式。具体实现如下:
2.1 全屏截图 全屏截图需要获取屏幕的大小,然后创建一个与屏幕大小相同的 BufferedImage 对象,在该对象上绘制屏幕上的内容。代码如下:
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
2.2 任意区域截图 任意区域截图需要在画布上显示一个矩形框,用户可以通过移动和调整该矩形框来选定截图区域。具体实现如下:
canvas.setOnMousePressed(event -> {
startX = event.getX();
startY = event.getY();
rect = new Rectangle(startX, startY, 0, 0);
rect.setStroke(Color.BLACK);
rect.setFill(Color.TRANSPARENT);
canvas.getChildren().add(rect);
});
canvas.setOnMouseDragged(event -> {
double endX = event.getX();
double endY = event.getY();
double width = endX - startX;
double height = endY - startY;
rect.setWidth(Math.abs(width));
rect.setHeight(Math.abs(height));
rect.setX(width > 0 ? startX : endX);
rect.setY(height > 0 ? startY : endY);
});
canvas.setOnMouseReleased(event -> {
double endX = event.getX();
double endY = event.getY();
double width = endX - startX;
double height = endY - startY;
rect.setWidth(Math.abs(width));
rect.setHeight(Math.abs(height));
rect.setX(width > 0 ? startX : endX);
rect.setY(height > 0 ? startY : endY);
WritableImage snapshot = canvas.snapshot(new SnapshotParameters(), null);
BufferedImage image = SwingFXUtils.fromFXImage(snapshot, null);
// 对 image 进行处理
});
2.3 窗口截图 窗口截图需要获取当前活动窗口的位置和大小,然后创建一个与窗口大小相同的 BufferedImage 对象,在该对象上绘制窗口的内容。代码如下:
Window window = Stage.getWindows().stream().filter(Window::isFocused).findFirst().orElse(null);
if (window != null) {
Rectangle2D bounds = window.getScene().getWindow().getBounds();
WritableImage snapshot = window.getScene().snapshot(null);
BufferedImage image = SwingFXUtils.fromFXImage(snapshot, null);
image = image.getSubimage(0, 0, (int) bounds.getWidth(), (int) bounds.getHeight());
// 对 image 进行处理
}
- 编辑功能设计 编辑功能包括画笔、橡皮擦、文字和箭头等工具。具体实现如下:
3.1 画笔 画笔需要记录鼠标按下和拖动时的坐标,然后在画布上绘制相应的线条。代码如下:
canvas.setOnMousePressed(event -> {
gc.beginPath();
gc.moveTo(event.getX(), event.getY());
});
canvas.setOnMouseDragged(event -> {
gc.lineTo(event.getX(), event.getY());
gc.stroke();
});
canvas.setOnMouseReleased(event -> {
// 记录最后一个点
gc.lineTo(event.getX(), event.getY());
gc.stroke();
});
3.2 橡皮擦 橡皮擦需要记录鼠标按下和拖动时的坐标,然后在画布上擦除相应的线条。代码如下:
canvas.setOnMousePressed(event -> {
gc.setGlobalCompositeOperation(BlendMode.DESTINATION_OUT);
gc.beginPath();
gc.moveTo(event.getX(), event.getY());
});
canvas.setOnMouseDragged(event -> {
gc.lineTo(event.getX(), event.getY());
gc.stroke();
});
canvas.setOnMouseReleased(event -> {
// 记录最后一个点
gc.lineTo(event.getX(), event.getY());
gc.stroke();
gc.setGlobalCompositeOperation(BlendMode.SOURCE_OVER);
});
3.3 文字 文字需要记录鼠标按下时的坐标和用户输入的文本,然后在画布上绘制相应的文本。代码如下:
canvas.setOnMouseClicked(event -> {
if (event.getButton() == MouseButton.PRIMARY) {
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle('Input Text');
dialog.setHeaderText(null);
dialog.setContentText('Please enter text:');
Optional<String> result = dialog.showAndWait();
if (result.isPresent()) {
String text = result.get();
gc.setFill(Color.BLACK);
gc.fillText(text, event.getX(), event.getY());
}
}
});
3.4 箭头 箭头需要记录鼠标按下和拖动时的坐标,然后在画布上绘制相应的线条和箭头。代码如下:
canvas.setOnMousePressed(event -> {
startX = event.getX();
startY = event.getY();
});
canvas.setOnMouseDragged(event -> {
double endX = event.getX();
double endY = event.getY();
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.strokeLine(startX, startY, endX, endY);
drawArrow(gc, startX, startY, endX, endY);
});
canvas.setOnMouseReleased(event -> {
double endX = event.getX();
double endY = event.getY();
gc.strokeLine(startX, startY, endX, endY);
drawArrow(gc, startX, startY, endX, endY);
});
private void drawArrow(GraphicsContext gc, double startX, double startY, double endX, double endY) {
double length = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
double angle = Math.atan2(endY - startY, endX - startX);
double arrowAngle = Math.PI / 6;
double arrowLength = 10;
double x1 = endX - arrowLength * Math.cos(angle - arrowAngle);
double y1 = endY - arrowLength * Math.sin(angle - arrowAngle);
double x2 = endX - arrowLength * Math.cos(angle + arrowAngle);
double y2 = endY - arrowLength * Math.sin(angle + arrowAngle);
gc.strokeLine(endX, endY, x1, y1);
gc.strokeLine(endX, endY, x2, y2);
}
- 保存和复制功能设计 保存和复制功能需要将画布上的内容保存为图片或复制到剪贴板。具体实现如下:
4.1 保存功能 保存功能需要将画布上的内容保存为常见图片格式,包括 png 和 jpg 两种格式。代码如下:
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle('Save Image');
fileChooser.setInitialFileName('screenshot.png');
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter('PNG', '*.png'),
new FileChooser.ExtensionFilter('JPG', '*.jpg')
);
File file = fileChooser.showSaveDialog(null);
if (file != null) {
String format = file.getName().substring(file.getName().lastIndexOf('.') + 1);
try {
ImageIO.write(SwingFXUtils.fromFXImage(canvas.snapshot(null, null), null), format, file);
} catch (IOException e) {
e.printStackTrace();
}
}
4.2 复制功能 复制功能需要将画布上的内容复制到剪贴板。代码如下:
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putImage(canvas.snapshot(null, null));
clipboard.setContent(content);
四、总结 本文介绍了一款截图软件的详细设计,包括需求分析、技术选型和具体实现。通过本文的介绍,读者可以了解到如何使用 JavaFX 开发一款简单的图像处理软件。
原文地址: https://www.cveoy.top/t/topic/o0gh 著作权归作者所有。请勿转载和采集!