本文共 9256 字,大约阅读时间需要 30 分钟。
前序:
今天有幸,看到2位博主的文章,在此表示感谢。自己也动手实现了一下。
实现原理 请参考博主 https://www.cnblogs.com/dongkuo/p/8285162.html
另感谢博主 http://www.cnblogs.com/litblank/p/8267526.html 提供的基础部分代码,免去了我自己再写一边的麻烦。
由于第一篇是python 实现,楼主是JAVA出生,想通过java实现,刚好在评论中看到了 第二位博主的java实现连接,但是自己用博主的代码,测试发现效果并不理想,获取的位置点不对。。。可能是打开方式不对~~~0.0
遂根据第一位博主的思路,重新实现了一下,亲测3张图,基本都是ok 的,下面就看看代码部分的实现。
代码实现:
1 package code; 2 3 import java.awt.AWTException; 4 import java.awt.Graphics2D; 5 import java.awt.Transparency; 6 import java.awt.image.BufferedImage; 7 import java.io.File; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.io.LineNumberReader; 11 import java.util.Map; 12 import java.util.Map.Entry; 13 import java.util.TreeMap; 14 import javax.imageio.ImageIO; 15 16 public class Jump { 17 //存放图片的路径 18 static String file1 = "C:\\Users\\JJJ\\Desktop\\jump3.jpg"; 19 //始 扫描行,针对不同的手机分辨率可能不一样,需要修改,此处建议手工测量下坐上角跳跃步数的数字位置,估算出起始行 楼主的手机是se 像素是 1156*640 20 static int start_y = 200; 21 static boolean istest = false; 22 static int background_x = 10; //定义默认的背景色,一定是不会出现其他物体的位置 23 static int background_y = 580; 24 25 public static void main(String[] args) throws AWTException, InterruptedException, IOException { 26 istest = true; 27 28 29 System.out.println("开始:计算" + file1); 30 if (istest) { 31 cmd_java("cmd /c start adb.bat ", "C:\\Users\\JJJ\\Downloads\\cofface_adb\\cofface_adb_windows_v5.1");//批处理文件 32 } 33 BufferedImage bi = (BufferedImage) ImageIO.read(new File(file1)); 34 Maptreemap = new TreeMap (); 35 // 获取图像的宽度和高度 36 int width = bi.getWidth(); 37 int height = bi.getHeight(); 38 //小人中心点坐标 39 int poix = 0; 40 int poiy = 0; 41 //目标物体的最顶点X轴 和左边或右边的Y轴 42 int mubiaopoix1 = 0; 43 int mubiaopoiy2 = 0; 44 //目标中心点坐标 45 int mubiaopoix = 0; 46 int mubiaopoiy = 0; 47 BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 48 Graphics2D g2d = img.createGraphics(); 49 // 设置画布为透明 50 img = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); 51 // 扫描图片,获取小人的底部中心坐标 52 for (int i = start_y; i < height; i++) { 53 for (int j = 0; j < width; j++) { // 行扫描 54 int dip = bi.getRGB(j, i); 55 int p = dip; 56 int red = 0xff & (p >> 16); 57 int green = 0xff & (p >> 8); 58 int blue = 0xff & p; 59 // 目标人图形 60 if (i < (height / 1.5)) 61 { 62 if ((red > 53 && red < 59) && (green > 57 && green < 61) && (blue > 59 && blue < 103)) 63 { // 获取小人坐标,从中取除Y值最大的一个 64 treemap.put(i, j); 65 } 66 } 67 } 68 } 69 //获取最后的小人底部坐标 ,此处使用treemap 直接排好序,循环获取Y轴值最大的一个 70 for (Entry entry : treemap.entrySet()) 71 { 72 poiy = entry.getKey(); 73 poix = entry.getValue(); 74 } 75 //开始扫描目标物体的最上和最左坐标 ,扫描的Y最大值为当前小人的Y值 76 treemap.clear(); //清除前面的记录,准备存放目标物体的坐标 77 RGB rgb = null; 78 boolean frist = true; 79 RGB rgb_0 = pixToRgb(bi, background_x, background_y); //默认的背景色 80 for (int y = start_y; y < poiy; y++) { 81 int x = 0; 82 if (poix < width /2) //此处特别说明下,如果小人的坐标在整个屏幕的左边,则目标物体一定在右边,遂起始x轴从小人之后开始加20开始循环,反之则不用 83 { 84 x = poix + 20; 85 } 86 else 87 { 88 x = 20; 89 } 90 for (; x < width - 20; x++) { // 行扫描 91 int dip = bi.getRGB(x, y); 92 int p = dip; 93 RGB rgb_1 = pixToRgb(bi, x, y); 94 if(frist && rgbCz(rgb_0,rgb_1,10)) //如果不相同则说明找到了第一个点 95 { 96 mubiaopoix1 = x; 97 rgb = rgb_1; 98 frist = false; 99 continue;100 }101 if (!frist && rgbBcz(rgb,rgb_1,10))102 {103 treemap.put(x, y); //存放所有当前台面的像素点坐标,然后从中选出X值最小的一个,104 }105 }106 }107 //获取目标物体的坐标,如果是在右半边,则获取最后一个值的Y轴,如果是在左边,则获取第一个108 if (poix > width / 2)109 {110 for (Entry entry : treemap.entrySet())111 {112 mubiaopoiy2 = entry.getValue();113 break;114 }115 }116 else117 {118 for (Entry entry : treemap.entrySet())119 {120 mubiaopoiy2 = entry.getValue();121 }122 }123 //通过获取的2个点坐标计算出中心点位置124 mubiaopoix = mubiaopoix1;125 mubiaopoiy = mubiaopoiy2;126 //计算 小人与目标人物的距离127 int total = (mubiaopoix - poix) * (mubiaopoix - poix) + (mubiaopoiy - poiy) * (mubiaopoiy - poiy);128 double length = (double) Math.sqrt(total);129 double time = length * 1.35; //时间系数130 System.out.println("小人的坐标为:" + poix + "," + poiy);131 System.out.println("目标物体的坐标为:" + mubiaopoix + "," + mubiaopoiy);132 System.out.println("需要按压屏幕的时间为:" + time + "毫秒");133 }134 153 154 static InputStreamReader ir = null;155 static LineNumberReader input = null;156 157 public static void cmd_java(String cmd) throws IOException {158 Process process = Runtime.getRuntime().exec(cmd, null, new File("C:\\Users\\chenyd\\adb"));159 ir = new InputStreamReader(process.getInputStream());160 input = new LineNumberReader(ir);161 while (input.readLine() != null) {162 }163 input.close();164 ir.close();165 }166 167 public static void cmd_java(String cmd, String url) throws IOException {168 Process process = Runtime.getRuntime().exec(cmd, null, new File(url));169 ir = new InputStreamReader(process.getInputStream());170 input = new LineNumberReader(ir);171 while (input.readLine() != null) {172 System.out.println(11);173 }174 input.close();175 ir.close();176 }177 178 /**179 * 颜色的差值不在范围内180 */181 public static boolean rgbCz(RGB rgb_1, RGB rgb_2, int fd_rgb) {182 if (Math.abs(rgb_1.getRed() - rgb_2.getRed()) > fd_rgb && Math.abs(rgb_1.getGreen() - rgb_2.getGreen()) > fd_rgb183 && Math.abs(rgb_1.getBlue() - rgb_2.getBlue()) > fd_rgb) {184 return true;185 }186 return false;187 }188 189 /**190 * 颜色的差值在范围内191 */192 public static boolean rgbBcz(RGB rgb_1, RGB rgb_2, int fd_rgb) {193 if (Math.abs(rgb_1.getRed() - rgb_2.getRed()) < fd_rgb && Math.abs(rgb_1.getGreen() - rgb_2.getGreen()) < fd_rgb194 && Math.abs(rgb_1.getBlue() - rgb_2.getBlue()) < fd_rgb) {195 return true;196 }197 return false;198 }199 200 public static RGB pixToRgb(BufferedImage bi, int j, int i) {201 try {202 int dip = bi.getRGB(j, i);203 int p = dip;204 int red = 0xff & (p >> 16);205 int green = 0xff & (p >> 8);206 int blue = 0xff & p;207 return new RGB(j, i, red, green, blue);208 } catch (Exception e) {209 210 }211 return null;212 }213 214 }215 216 class RGB {217 218 public RGB() {219 }220 221 public RGB(int x, int y, int red, int green, int blue) {222 super();223 X = x;224 Y = y;225 this.red = red;226 this.green = green;227 this.blue = blue;228 }229 230 public int X;231 public int Y;232 public int red;233 public int green;234 public int blue;235 236 public int getRed() {237 return red;238 }239 240 public void setRed(int red) {241 this.red = red;242 }243 244 public int getGreen() {245 return green;246 }247 248 public void setGreen(int green) {249 this.green = green;250 }251 252 public int getBlue() {253 return blue;254 }255 256 public void setBlue(int blue) {257 this.blue = blue;258 }259 260 public int getX() {261 return X;262 }263 264 public void setX(int x) {265 X = x;266 }267 268 public int getY() {269 return Y;270 }271 272 public void setY(int y) {273 Y = y;274 }275 276 }
由于楼主目前没有安卓设备,还无法带上adb实验,目前只是通过手动截取图片,和测量距离计算了3张,总体比较下来,还算是正确的。
第一张图片
计算结果如图:
第二张图片
计算结果如图:
第三张图片
计算结果如图:
后续再搞个安卓设备试试~
give me the ball!