一、图像处理在自动化中使用场景
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;
}
}