今天分享的這個(gè)技能可以說是灰常有用,做自動(dòng)化測試,無論是Web端的Selenium(Appium的使用基本類似Selenium)還是移動(dòng)端的UiAutomator2.0都有提供相應(yīng)的截屏API,直接調(diào)用對應(yīng)方法輕松截屏,可是問題來了,很多時(shí)候我并不想截取整個(gè)屏幕,除了整屏圖片太大外,還有有時(shí)候我還需要二次處理,比如常見的對指定位置進(jìn)行背景色提取、樣式、文字或數(shù)據(jù)驗(yàn)證等,這時(shí)候就需要我們精準(zhǔn)的截取需要的部分,從而排除無關(guān)的干擾區(qū)域。這要怎么做?下面就以Selenium和UiAutomator2.0的實(shí)現(xiàn)代碼來演示……
思路
大致思路是在截取整屏后,我們根據(jù)坐標(biāo)和截取區(qū)域大小,再次去截取對應(yīng)的小圖,因此要精準(zhǔn)截圖,這就要以我們能獲取到的控件元素或?qū)ο鬄榛A(chǔ),通過對應(yīng)的對象獲取該對象在屏幕中的的坐標(biāo),以及對象的區(qū)域(長、寬)等信息,有了這些信息就可以通過代碼輕松截取指定位置和區(qū)域的圖了。下面看具體實(shí)現(xiàn):
Selenium實(shí)現(xiàn)精準(zhǔn)截圖
你可以讓最終結(jié)果返回一個(gè)File對象,指向?qū)?yīng)的截圖后的文件對象,也可以直接返回截圖后的文件路徑(返回路徑:file.getAbsolutePath()),這個(gè)根據(jù)需要,自己去選擇。
private File snapshotAndSave(WebElement element, String filePath) {
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//截圖整個(gè)頁面
try {
BufferedImage img = ImageIO.read(scrFile);
// 獲得元素的高度和寬度
int width = element.getSize().getWidth();
int height = element.getSize().getHeight() ;
// 創(chuàng)建一個(gè)矩形使用上面的高度,和寬度
Rectangle rect = new Rectangle(width, height);
// 得到元素的起始坐標(biāo)
int x = element.getLocation().getX();
int y = element.getLocation().getY();
//開始按坐標(biāo)和區(qū)域截圖
BufferedImage dest = img.getSubimage(x, y, rect.width, rect.height);
//存為png格式
ImageIO.write(dest, SNAPSHOT_IMG_SUFFIX, scrFile);
File file = new File(filePath);
FileUtils.copyFile(scrFile, file);
return file;
} catch (Exception e) {
LOGGER.error("snapshotAndSave error:", e);
}
return null;
}
UiAutomator2.0實(shí)現(xiàn)精準(zhǔn)截圖
實(shí)現(xiàn)思路跟Selenium幾乎是一樣的,這里傳入了一個(gè)paths數(shù)組(當(dāng)然你也可以改一下分開傳2個(gè)參數(shù)),傳一個(gè)就代表截屏和后面的再次截圖是用的同一個(gè)路徑,傳2個(gè)就對應(yīng)分開了。返回對應(yīng)圖片文件對象還是路徑根據(jù)自己需要去調(diào)整了。(注:鑒于排版,有些I/O的規(guī)范就沒遵循了,用的時(shí)候自己去調(diào)整下流的關(guān)閉位置)
public static String takeElementshot(UiObject2 object, String...paths) {
if (paths == null || paths.length < 1) {
throw new IllegalArgumentException("paths參數(shù)不能為空");
}
if (object == null) {
return null;
}
try {
File file = new File(paths[0]);
mDevice.takeScreenshot(file);
BitmapFactory.Options bfOptions = new BitmapFactory.Options();
bfOptions.inDither = false;
bfOptions.inTempStorage = new byte[12 * 1024];
bfOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(paths[0]);
Rect rect = object.getVisibleBounds();
bitmap = bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height());//獲取區(qū)域
String jpgCutPath = paths.length > 1 ? paths[1] : paths[0];
File filePic = new File(jpgCutPath);
if (!filePic.exists()) {
filePic.createNewFile();
}
FileOutputStream fos = new FileOutputStream(jpgCutPath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
return filePic.getAbsolutePath();
} catch (Exception e) {
return null;
}
}
怕有童鞋看不清楚,給個(gè)調(diào)用的例子演示一下:
String jpgPath = Config.LOG_PATH + "ocr.jpg";
String jpgCutPath = Config.LOG_PATH + "ocr_cut.jpg";
String path = takeElementshot(object, jpgPath, jpgCutPath);
原文來自下方公眾號,轉(zhuǎn)載請聯(lián)系作者,并務(wù)必保留出處。
想第一時(shí)間看到更多原創(chuàng)技術(shù)好文和資料,請關(guān)注公眾號:測試開發(fā)棧