一、图像处理在自动化中使用场景
1)效果类截图
图像处理技术在自动化的场景中很容易使用到。自动化不是万能的,有时候效果类的是无法进行验证的,但是效果类一般会有图像显示,我们可以通过截图对比实现。
2)不可见的组件图像对比
uiautomator依赖于组件的可见性,组件不可见的时候,那组件里的信息也是不可读到的,类似ImgButton,它的状态一旦变化,我们就没有办法判断,这种可以使用图像进行对比。
3)失败与异常截图
还有时候,用例运行失败,我们想知道失败的时候场景是怎么样子的,就需要失败异常的截图。
4)利用图像判断组件
有时候,有些组件,比如播放键,播放与暂停是用图片代替的, 这时候我们不能获取组件信息,这时候我们就可以用图像对比来获取信息。
二、BitMap图像处理
1.部分API简单说明
BitMap给我们提供很多图片的处理方法。
这边简单的列了一些API
API | 说明 |
compress | 压缩图片 |
copy | 复制图片 |
createBitmap | 创建图片 |
getHeight | 获取图片高度 |
getWidth | 获取图片宽度 |
getPixel | 获取某个点颜色值 |
setPixel | 设置某个点颜色值 |
三、图像处理实例
package com.yoyo.testsuites; import java.lang.Exception; import java.io.File; import java.io.FileOutputStream; import com.android.uiautomator.core.UiDevice; import com.android.uiautomator.core.UiObject; import com.android.uiautomator.core.UiObjectNotFoundException; import com.android.uiautomator.core.UiSelector; import com.android.uiautomator.testrunner.UiAutomatorTestCase; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; public class bitmapBase extends UiAutomatorTestCase { //快速调试 public static void main(String[] args) { String jarName = "TestYoyo"; String testClass = "com.yoyo.testsuites.bitmapBase"; String testName = "runTest"; String androidId = "5"; new UiAutomatorHelper(jarName, testClass, testName, androidId); } UiDevice device = UiDevice.getInstance(); //用例 public void runTest() throws UiObjectNotFoundException { //创建bitmap crateBitmap("bitmap"); //截取组件图片 UiObject object=new UiObject(new UiSelector().resourceId("dianyun.baobaowd:id/checkin_iv")); cutImg(object,"screenshot","checkinImg"); //获取截图中(100,200)坐标位置的颜色值 int colorValue=getColor(100,200,"ColorImg"); System.out.println("该坐标点的颜色值为="+colorValue); //截图并嵌入文字 scrennshotAndDrawnText("screenshot","textImg", "截图并嵌入文字"); //截取组件,与保存的组件原图进行对比 UiObject object2 =new UiObject(new UiSelector().resourceId("dianyun.baobaowd:id/checkin_iv")); cutImg(object2, "screenshot", "moduleImg");//截取组件图 String targetImgPath="mnt/sdcard/yoyoTargetImg/checkImg.jpg";//已保存将用来做对比的截图 String comPath="mnt/sdcard/yoyoTest/moduleImg.jpg"; double percent=0.9; //调用图像对比方法 boolean b=imgSameAs(targetImgPath,comPath,percent); //输出对比结果 System.out.println("图像比对结果:"+b); } /*-------------------图像处理方法---------------------*/ //创建bitmap public void crateBitmap(String ImgName) { //截取一张图片 String path="mnt/sdcard/yoyoTest/takescreenshot.jpg"; File file=new File(path); device.takeScreenshot(file); sleep(1000); //将图片重命名保存 //先将截图通过BitmapFactory(bitmap工厂模式)创建为bitmap,然后将bitmap压缩保存 Bitmap bitmap=BitmapFactory.decodeFile(path); saveBitMapToSdcard(bitmap,ImgName); } //压缩保存bitmap图 public void saveBitMapToSdcard(Bitmap bitmap,String ImgName){ FileOutputStream out=null; try { out=new FileOutputStream("/mnt/sdcard/yoyoTest/"+ImgName+".jpg"); if(out!=null){ //三个参数分别为格式、保存的文件质量90为原图的90%、文件流 bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); out.close(); } } catch (Exception e) { throw new RuntimeException(e); } } //组件区域截图 //object:组件的object public void cutImg(Object object,String screenshotName,String moduleImgName) throws UiObjectNotFoundException { //截取图片并保存至path String path="/mnt/sdcard/yoyoTest/"+screenshotName+".png"; File file=new File(path); UiDevice.getInstance().takeScreenshot(file); //根据path路径找到截图,截取组件图 Bitmap m=BitmapFactory.decodeFile(path); Rect rect = ((UiObject) object).getBounds(); m=Bitmap.createBitmap(m,rect.left,rect.top,rect.width(),rect.height()); //保存组件截图 saveBitMapToSdcard(m, moduleImgName); } //获取某一点的颜色值 public int getColor(int x,int y,String ImgName) { String path="/mnt/sdcard/yoyoTest/"+ImgName+".jpg"; File file =new File(path); device.takeScreenshot(file); Bitmap bitmap=BitmapFactory.decodeFile(path); int color=bitmap.getPixel(x,y); System.out.println(color); return color; } //图像嵌入文字 public void scrennshotAndDrawnText(String screenshotName,String textImgName,String text) { String path="/mnt/sdcard/yoyoTest/"+screenshotName+".jpg"; File file =new File(path); device.takeScreenshot(file); Bitmap bitmap=BitmapFactory.decodeFile(path); Bitmap drawBitmap=drawTextBitmap(bitmap,text); saveBitMapToSdcard(drawBitmap, textImgName);//调用嵌入文字方法 } //嵌入文字方法 private Bitmap drawTextBitmap(Bitmap bitmap, String text) { int x=bitmap.getWidth(); int y=bitmap.getHeight(); ///创建一个更大的位图,Config.ARGB_8888为创建的位图的信息,32位 Bitmap newBitmap=Bitmap.createBitmap(x,y+80,Bitmap.Config.ARGB_8888); //创建画布 Canvas canvans=new Canvas(newBitmap); //创建画笔 Paint paint=new Paint(); //在原图位置(0,0)叠加一张图片 canvans.drawBitmap(bitmap, 0, 0,paint); //画笔颜色 paint.setColor(Color.parseColor("#FF0000")); paint.setTextSize(80);//设置文字大小 canvans.drawText(text, 300, y+55, paint);//写字 canvans.save(Canvas.ALL_SAVE_FLAG);//保存 canvans.restore(); return newBitmap; } //图像对比 public boolean imgSameAs(String targetImgPath,String comPath,double percent) { try { //创建两个bitmap Bitmap targetImg=BitmapFactory.decodeFile(targetImgPath); Bitmap compareImg=BitmapFactory.decodeFile(comPath); //声明变量 int width=compareImg.getWidth(); int height=compareImg.getHeight(); int numDiffPixels=0;//两张图片像素差 for (int y= 0; y< height ;y++) { for(int x=0;x<width;x++){ //取不相等的像素值 if (compareImg.getPixel(x, y)!=targetImg.getPixel(x, y)) { numDiffPixels++; } } } double totalPixels=width*height;//像素值总量=width*height double diffPercent=numDiffPixels/totalPixels;//差异度百分比=不等像素值/像素值总量 System.out.println(1.0-diffPercent);//相似度百分比=1.0-差异度百分比 return percent<=1.0-diffPercent; } catch (Exception e) { } return false; } }