package cn.xjiangwei.RobotHelper.Tools; import android.app.Dialog; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Base64; import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; import org.opencv.android.Utils; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.LinkedList; import cn.xjiangwei.RobotHelper.R; public class Image { /** * 保存图片到图库 * Image.saveImageToGallery(bt, getExternalFilesDir("").getAbsolutePath() + "/asdf.png"); * * @param bmp */ public static void saveImageToGallery(Bitmap bmp, String bitName) { File file = new File(bitName); try { FileOutputStream fos = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 打开本地图片 * * @param path * @return */ public static Bitmap openImg(String path) { Bitmap ret = BitmapFactory.decodeFile(path); if (ret == null) { MLog.error("打开" + path + "失败!"); } return ret; } /** * 单点找色 * * @param img * @param color * @return */ public static LinkedList<Point> findPoint(Bitmap img, Color color) { LinkedList<Point> pl = new LinkedList<Point>(); int width = img.getWidth(); int height = img.getHeight(); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (Color.isSame(getPoint(img, i, j), color)) { pl.add(new Point(i, j)); } } } return pl; } /** * 多色找点 * 在屏幕某个范围内 * * @param img * @param colorRules * @param leftX * @param leftY * @param rightX * @param rightY * @return */ public static Point findPointByMulColor(Bitmap img, String colorRules, int leftX, int leftY, int rightX, int rightY) { img = cropBitmap(img, leftX, leftY, rightX, rightY); Point p = findPointByMulColor(img, colorRules); if (p.isEmpty()) { return p; } return new Point(p.getX() + leftX, p.getY() + leftY); } /** * 多色找点函数 * * @param img * @param colorRules * @return */ public static Point findPointByMulColor(Bitmap img, String colorRules) { long now = System.currentTimeMillis(); int[] colors = new int[img.getWidth() * img.getHeight()]; String[] res = colorRules.split(","); Color firstPointColor = HexColor2DecColor(res[0], true); img.getPixels(colors, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight()); for (int i = 0; i < colors.length; i++) { if (Color.isSame(new Color(colors[i]), firstPointColor)) { int y = (int) (i / img.getWidth()); int x = i % img.getWidth(); for (int k = 1; k < res.length; k++) { res[k] = res[k].replace("\"", ""); String[] info = res[k].split("\\|"); int testX = x + Integer.parseInt(info[0]); int testY = y + Integer.parseInt(info[1]); if (testX < 0 || testY < 0 || testX > img.getWidth() || testY > img.getHeight()) { break; } Color nextColor = getPoint(img, testX, testY); if (!Color.isSame(nextColor, HexColor2DecColor(info[2], true))) { break; } else { if (k == (res.length - 1)) { MLog.info("找点用时:", String.valueOf(System.currentTimeMillis() - now)); return new Point(x, y); } } } } } return new Point(-1, -1); } /** * 多色找点,自定义颜色误差 * * @param img * @param colorRules * @param offset * @return */ public static Point findPointByMulColor(Bitmap img, String colorRules, int offset) { long now = System.currentTimeMillis(); // 将图像转换成颜色数组 int[] colors = new int[img.getWidth() * img.getHeight()]; String[] res = colorRules.split(","); Color firstPointColor = HexColor2DecColor(res[0], true); img.getPixels(colors, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight()); //遍历颜色数组 for (int i = 0; i < colors.length; i++) { // 寻找规则中第一个点 if (Color.isSame(new Color(colors[i]), firstPointColor, offset)) { // 第一个点的y坐标 int y = (int) (i / img.getWidth()); // 第一个点的x坐标 int x = i % img.getWidth(); // 检查规则中后续每个点 for (int k = 1; k < res.length; k++) { //处理规则中多余的引号 res[k] = res[k].replace("\"", ""); String[] info = res[k].split("\\|"); int testX = x + Integer.parseInt(info[0]); int testY = y + Integer.parseInt(info[1]); //超出图片范围 if (testX < 0 || testY < 0 || testX > img.getWidth() || testY > img.getHeight()) { break; } Color nextColor = getPoint(img, testX, testY); if (!Color.isSame(nextColor, HexColor2DecColor(info[2], true), offset)) { break; } else { if (k == (res.length - 1)) { return new Point(x, y); } } } } } MLog.info("找点用时:", String.valueOf(System.currentTimeMillis() - now)); return new Point(-1, -1); } /** * 已废弃 * * @param img * @param colorRules * @return * @deprecated */ public static Point findPointByMulColorBack(Bitmap img, String colorRules) { long now = System.currentTimeMillis(); String[] res = colorRules.split(","); Color firstPointColor = HexColor2DecColor(res[0], true); int imgWidth = img.getWidth(); int imgHeight = img.getHeight(); for (int i = 0; i < imgWidth; i++) { for (int j = 0; j < imgHeight; j++) { if (Color.isSame(getPoint(img, i, j), firstPointColor)) { for (int k = 1; k < res.length; k++) { res[k] = res[k].replace("\"", ""); String[] info = res[k].split("\\|"); int testX = i + Integer.parseInt(info[0]); int testY = j + Integer.parseInt(info[1]); if (testX < 0 || testY < 0 || testX > imgWidth || testY > imgHeight) { break; } Color nextColor = getPoint(img, testX, testY); if (!Color.isSame(nextColor, HexColor2DecColor(info[2], true))) { break; } else { if (k == (res.length - 1)) { MLog.info("找点用时:", String.valueOf(System.currentTimeMillis() - now)); return new Point(i, j); } } } } } } MLog.info("找点用时:", String.valueOf(System.currentTimeMillis() - now)); return new Point(-1, -1); } /** * 多色找点,返回屏幕内全部满足规则的点 * * @param img * @param colorRules * @return */ public static LinkedList<Point> findPointsByMulColor(Bitmap img, String colorRules) { LinkedList<Point> ret = new LinkedList<Point>(); String[] res = colorRules.split(","); Color firstPointColor = HexColor2DecColor(res[0], true); int imgWidth = img.getWidth(); int imgHeight = img.getHeight(); for (int i = 0; i < imgWidth; i++) { for (int j = 0; j < imgHeight; j++) { if (Color.isSame(getPoint(img, i, j), firstPointColor)) { for (int k = 1; k < res.length; k++) { res[k] = res[k].replace("\"", ""); String[] info = res[k].split("\\|"); int testX = i + Integer.parseInt(info[0]); int testY = j + Integer.parseInt(info[1]); if (testX < 0 || testY < 0 || testX > imgWidth || testY > imgHeight) { break; } Color nextColor = getPoint(img, testX, testY); if (!Color.isSame(nextColor, HexColor2DecColor(info[2], true))) { break; } else { if (k == (res.length - 1)) { ret.add(new Point(i, j)); } } } } } } return ret; } /** * @param color * @return */ public static Color HexColor2DecColor(String color) { color = color.replace("#", ""); color = color.replace("\"", ""); try { int r = Integer.parseInt(color.substring(0, 2), 16); int g = Integer.parseInt(color.substring(2, 4), 16); int b = Integer.parseInt(color.substring(4, 6), 16); return new Color(r, g, b); } catch (Exception e) { return new Color(); } } /** * @param color * @param bgr * @return */ public static Color HexColor2DecColor(String color, boolean bgr) { color = color.replace("#", ""); color = color.replace("\"", ""); try { int b = Integer.parseInt(color.substring(0, 2), 16); int g = Integer.parseInt(color.substring(2, 4), 16); int r = Integer.parseInt(color.substring(4, 6), 16); return new Color(r, g, b); } catch (Exception e) { return new Color(); } } /** * 获取一个点的颜色 * * @param img * @param x * @param y * @return */ public static Color getPoint(Bitmap img, int x, int y) { try { return new Color(img.getPixel(x, y)); } catch (IllegalArgumentException e) { return new Color(0, 0, 0); } } /** * 预览图片 * * @param img * @param context */ public static void show(Bitmap img, Context context) { Dialog dia = new Dialog(context, R.style.edit_AlertDialog_style2); dia.setContentView(R.layout.activity_start_dialog); ImageView imageView = (ImageView) dia.findViewById(R.id.start_img); imageView.setImageBitmap(img); dia.show(); dia.setCanceledOnTouchOutside(true); // Sets whether this dialog is Window w = dia.getWindow(); WindowManager.LayoutParams lp = w.getAttributes(); lp.x = 0; lp.y = 40; dia.onWindowAttributesChanged(lp); } /** * 裁剪 * * @param bitmap * @param leftTopX * @param leftTopY * @param rightBottomX * @param rightBottomY * @return */ public static Bitmap cropBitmap(Bitmap bitmap, int leftTopX, int leftTopY, int rightBottomX, int rightBottomY) { return Bitmap.createBitmap(bitmap, leftTopX, leftTopY, rightBottomX - leftTopX, rightBottomY - leftTopY, null, false); } /** * base64 图片 * * @param bitmap * @return */ public static String encodeImage(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); //读取图片到ByteArrayOutputStream bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); //参数如果为100那么就不压缩 byte[] bytes = baos.toByteArray(); return Base64.encodeToString(bytes, Base64.DEFAULT); } /** * 模板匹配 * * @param srcImg //源图像 * @param templateImg //模板图像 * @param threshold //相识度阈值,阈值调小可以一定程度解决不同手机分辨率的问题 * @return //如果没有找到则返回(-1,-1)点 */ public static Point matchTemplate(Bitmap srcImg, Bitmap templateImg, double threshold) { if (threshold <= 0) { threshold = 0.5; } Mat tpl = new Mat(); Mat src = new Mat(); Utils.bitmapToMat(srcImg, src); Utils.bitmapToMat(templateImg, tpl); int height = src.rows() - tpl.rows() + 1; int width = src.cols() - tpl.cols() + 1; Mat result = new Mat(height, width, CvType.CV_32FC1); int method = Imgproc.TM_CCOEFF_NORMED; Imgproc.matchTemplate(src, tpl, result, method); Core.MinMaxLocResult minMaxResult = Core.minMaxLoc(result); org.opencv.core.Point maxloc = minMaxResult.maxLoc; if (minMaxResult.maxVal < threshold) { return new Point(-1, -1); } org.opencv.core.Point minloc = minMaxResult.minLoc; org.opencv.core.Point matchloc = null; matchloc = maxloc; return new Point((int) matchloc.x, (int) matchloc.y); } }