Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之整体思路篇 Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之图片分割篇 Java版本的基于计算机视觉的跃动小子保卫主公自动通关计划之执行计划生成篇
对于图像分割,尤其是在游戏或其他视觉应用中,准确地将屏幕内容切割成若干个小区域是常见的需求。在本文中,我们介绍了如何通过Java的BufferedImage类实现屏幕的截取,并将图片分割成多个小块,重点分析两种实现方法:计算式分割和手动测量式分割,并提出了适合的优化方案。
获取桌面代码
public static BufferedImage screenCapture() {
// 获取屏幕大小
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// 创建BufferedImage对象,捕获屏幕图像
return getRobot().createScreenCapture(new Rectangle(screenSize));
}图片切割核心api为java.awt.image.BufferedImage#getSubimage(int x, int y, int w, int h),只需要计算出每个小格子的起始坐标即可,长和高是固定的.
获取长和高有两种思路,一直是计算,另一种是测量
通过数学公式计算每个小格子的x和y坐标,确保每个小格子被准确地分割出来。这里我们假设每个格子之间有固定的间隔(边框宽度),即横向和纵向都有固定的边距。

第一个点的x坐标为(cw+bw)*0
第二个点的x坐标为(cw+bw)*1
第三个点的x坐标为(cw+bw)*2
…以此类推,y坐标同理
图片分割代码
@SneakyThrows
public void split(BufferedImage image,int rows,int cols,int startX,int startY,int cellWidth,int cellHeight,int vBorder,int hBorde,String outputDir) {
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
// 计算每个小格子的位置
int x = startX + (cellWidth + vBorder) * col;
int y = startY + (cellHeight + hBorde) * row;
BufferedImage subImage = image.getSubimage(x, y, cellWidth, cellHeight);
// 保存小格子图像
String outputImagePath = String.format("%s/%d_%d.jpg", outputDir, row, col);
try {
ImageIO.write(subImage, "jpg", new File(outputImagePath));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}此方法理论上比较合适,实际上在测量过程中很难完全准确,导致截取的最左边的一列总是多一块或者少一块,最下边的也是多一块或者少一块,很难调,因此只做简单介绍
由于游戏界面往往有复杂的背景或边界难以精确计算,因此可以通过手动测量来确定每列和每行的坐标,避免误差。我们可以使用工具(如微信截图工具)获取每个小格子确切的x和y坐标,然后直接利用这些坐标分割图片。
@SneakyThrows
public static void split(BufferedImage image, List<Integer> xs, List<Integer> ys, int width, int height, String outputDir) {
int i = 0;
for (Integer row : xs) {
int j = 0;
for (Integer col : ys) {
BufferedImage subimage = image.getSubimage(row, col, width, height);
String outputImagePath = String.format("%s/%d_%d.jpg", outputDir, j, i);
ImageIO.write(subimage, "jpg", new File(outputImagePath));
j++;
}
i++;
}
}实测
BufferedImage bufferedImage = RobotUtils.screenCapture();
List<Integer> xs = Arrays.asList(738, 813, 888, 963, 1036, 1111);
List<Integer> ys = Arrays.asList(340, 413, 484, 556, 631, 703);
int width = 70;
int height = 68;
String outputDir = "src/main/resources/img/xxl/subImage";
ImageSplitter.split(bufferedImage, xs, ys, width, height, outputDir);
log.info("图片截取完成");通过测量方法,我们能够确保图像分割精准无误,消除了边框不对齐的问题。手动调整x和y坐标后,分割效果如下:

在游戏截图等复杂场景下,推荐使用手动测量法,尤其是当每个小格子的边界并不明确时,可以根据效果微调坐标,得到理想的分割结果。
如果图片分割精度非常关键,可以通过手动方式结合程序化的自动分割,最大化提升效率和准确性。