如何实现Java截图分析程序从图像中心向外遍历检测指定像素
实现思路
这里提供两种可行方案,可根据实际使用场景选择:
方案1:逐层向外遍历(推荐,性能更高)
无需提前生成全量坐标,按到中心点的层级从内到外遍历,找到目标像素即可立刻终止,适配你当前找到红色就跳出的逻辑:
- 用变量
d表示当前遍历的层级(即与中心点的切比雪夫距离),从0开始递增,最大到250即可覆盖全图 - 每个层级遍历x偏移、y偏移的所有组合,同时校验坐标落在0~499的合法范围内
- 每检测一个像素就判断是否符合条件,符合直接跳出所有循环
对应实现代码:
int center = 250; int maxOffset = 250; // 500尺寸图像最大偏移就是250 breakthis : { // 从中心开始逐层向外,d是当前层级的偏移量 for (int d = 0; d <= maxOffset; d++) { // 遍历当前层级所有x偏移 for (int xOffset = -d; xOffset <= d; xOffset++) { int xpos = center + xOffset; // 校验x坐标合法 if (xpos < 0 || xpos >= 500) continue; // 遍历当前层级所有y偏移 for (int yOffset = -d; yOffset <= d; yOffset++) { // 保证只遍历当前层级的边界,避免重复检测内层已经查过的点 if (Math.abs(xOffset) != d && Math.abs(yOffset) != d) continue; int ypos = center + yOffset; // 校验y坐标合法 if (ypos <0 || ypos >=500) continue; int color = image.getRGB(xpos, ypos); int red = (color & 0x00ff0000) >> 16; int green = (color & 0x0000ff00) >> 8; int blue = color & 0x000000ff; if (red == 255) { System.out.println("Red has been found inside the picture"); break breakthis; } } } } }
如果要严格按照欧氏距离排序的遍历顺序,只需要把上面的层级判断条件替换为欧氏距离校验即可。
方案2:全量坐标按距离排序后遍历
就是你提到的思路实现,适合需要全量按距离顺序处理所有像素的场景,缺点是需要提前生成25万个坐标并排序,找到目标就终止的场景下性能不如方案1:
int center = 250; List<int[]> points = new ArrayList<>(); // 生成所有坐标 for (int x = 0; x < 500; x++) { for (int y = 0; y < 500; y++) { points.add(new int[]{x, y}); } } // 按到中心点的欧氏距离从小到大排序 Collections.sort(points, (p1, p2) -> { double d1 = Math.hypot(p1[0] - center, p1[1] - center); double d2 = Math.hypot(p2[0] - center, p2[1] - center); return Double.compare(d1, d2); }); breakthis : { for (int[] point : points) { int xpos = point[0]; int ypos = point[1]; int color = image.getRGB(xpos, ypos); int red = (color & 0x00ff0000) >> 16; int green = (color & 0x0000ff00) >> 8; int blue = color & 0x000000ff; if (red == 255) { System.out.println("Red has been found inside the picture"); break breakthis; } } }
内容的提问来源于stack exchange,提问作者iowna
相关产品推荐
相关产品推荐

