如何使用 Python 代码在 Appium 中比较图片?
How to compare a picture in Appium, using Python code?
我需要在 iOS 应用程序中比较模板图片。我需要使用什么语法?我找到了很多关于它的信息,但只有 Java 语法。
我在 Mac 上使用 Appium + Python。
我猜您已经使用 get_screenshot_as_base64()
(here 文档)检索了模板图像和真实图像(以检查模板)。
那么你可以尝试使用Appium内嵌的OpenCV库来检查两张图片的相似程度,通过调用函数get_images_similarity()
(here实现)得到相似度分数两张图片并在上面进行推理。
有关更多详细信息,请查看 this 有用的文章!
我尝试用 OpenCV 库将图片与模板进行比较。我就是这样做的:
将方法添加到 base_page.py
。
def compare_image_with_screenshot(self, image_name: str):
os.chdir('../src/screenshots/')
with open(f'{image_name}.png', 'rb') as img:
first_image = base64.b64encode(img.read()).decode('ascii')
second_image = base64.b64encode(self._driver.get_screenshot_as_png()).decode('ascii')
return self._driver.get_images_similarity(first_image, second_image)
在页面对象文件中使用此方法。
@allure.step('Compare screenshot with template')
def get_image_comparison_percents(self):
"""
This method gets screenshot on device with template in repo. Comparison result is percentage of similarity. Test is OK if comparison more than 90%
"""
result = self.compare_image_with_screenshot(OfflineLocators.offline_stub)
return result.get('score')
在必要的测试中使用步骤。
@allure.link(url='https://jira.myproject.tech/browse/TEST-1', name='TEST-1 - Offline stub')
@allure.title('Offline stub')
def test_offline_stub(appdriver):
TourActions(appdriver).skip_tour()
Navigation(appdriver).open_my_offline_page()
assert Offline(appdriver).get_page_title_text() == 'Offline'
assert Offline(appdriver).get_image_comparison_percents() > 0.9
所有这一切的结果是我得到了一定比例的图片相似度。它可以是您需要的那个百分比。我的测试没问题。
我无法使用 openCV 库。
因为我无法安装opencv4nodejs
您可以尝试使用 npm 模块以这种方式安装它:npm i -g opencv4nodejs
所以,我找到了比较图像的解决方案。您可以使用此代码:
/**
* Finds the a region in one image that best matches another, smaller, image.
*/
public static int[] findSubImage(BufferedImage im1, BufferedImage im2){
int w1 = im1.getWidth(); int h1 = im1.getHeight();
int w2 = im2.getWidth(); int h2 = im2.getHeight();
assert(w2 <= w1 && h2 <= h1);
// will keep track of best position found
int bestX = 0; int bestY = 0; double lowestDiff = Double.POSITIVE_INFINITY;
// brute-force search through whole image (slow...)
for(int x = 0;x < w1-w2;x++){
for(int y = 0;y < h1-h2;y++){
double comp = compareImages(im1.getSubimage(x,y,w2,h2),im2);
if(comp < lowestDiff){
bestX = x; bestY = y; lowestDiff = comp;
}
}
}
// output similarity measure from 0 to 1, with 0 being identical
System.out.println(lowestDiff + "output similarity measure from 0 to 1, with 0 being identical");
Assertions.assertTrue(lowestDiff<0.5);
// return best location
return new int[]{bestX,bestY};
}
/**
* Determines how different two identically sized regions are.
*/
public static double compareImages(BufferedImage im1, BufferedImage im2){
assert(im1.getHeight() == im2.getHeight() && im1.getWidth() == im2.getWidth());
double variation = 0.0;
for(int x = 0;x < im1.getWidth();x++){
for(int y = 0;y < im1.getHeight();y++){
variation += compareARGB(im1.getRGB(x,y),im2.getRGB(x,y))/Math.sqrt(3);
}
}
return variation/(im1.getWidth()*im1.getHeight());
}
/**
* Calculates the difference between two ARGB colours (BufferedImage.TYPE_INT_ARGB).
*/
public static double compareARGB(int rgb1, int rgb2){
double r1 = ((rgb1 >> 16) & 0xFF)/255.0; double r2 = ((rgb2 >> 16) & 0xFF)/255.0;
double g1 = ((rgb1 >> 8) & 0xFF)/255.0; double g2 = ((rgb2 >> 8) & 0xFF)/255.0;
double b1 = (rgb1 & 0xFF)/255.0; double b2 = (rgb2 & 0xFF)/255.0;
double a1 = ((rgb1 >> 24) & 0xFF)/255.0; double a2 = ((rgb2 >> 24) & 0xFF)/255.0;
// if there is transparency, the alpha values will make difference smaller
return a1*a2*Math.sqrt((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2));
}
我找到了 here。
它工作得很好,但太慢了。
如果你也不会使用openCV,你可以使用这种方式。
祝你好运。
我需要在 iOS 应用程序中比较模板图片。我需要使用什么语法?我找到了很多关于它的信息,但只有 Java 语法。
我在 Mac 上使用 Appium + Python。
我猜您已经使用 get_screenshot_as_base64()
(here 文档)检索了模板图像和真实图像(以检查模板)。
那么你可以尝试使用Appium内嵌的OpenCV库来检查两张图片的相似程度,通过调用函数get_images_similarity()
(here实现)得到相似度分数两张图片并在上面进行推理。
有关更多详细信息,请查看 this 有用的文章!
我尝试用 OpenCV 库将图片与模板进行比较。我就是这样做的:
将方法添加到
base_page.py
。def compare_image_with_screenshot(self, image_name: str): os.chdir('../src/screenshots/') with open(f'{image_name}.png', 'rb') as img: first_image = base64.b64encode(img.read()).decode('ascii') second_image = base64.b64encode(self._driver.get_screenshot_as_png()).decode('ascii') return self._driver.get_images_similarity(first_image, second_image)
在页面对象文件中使用此方法。
@allure.step('Compare screenshot with template') def get_image_comparison_percents(self): """ This method gets screenshot on device with template in repo. Comparison result is percentage of similarity. Test is OK if comparison more than 90% """ result = self.compare_image_with_screenshot(OfflineLocators.offline_stub) return result.get('score')
在必要的测试中使用步骤。
@allure.link(url='https://jira.myproject.tech/browse/TEST-1', name='TEST-1 - Offline stub') @allure.title('Offline stub') def test_offline_stub(appdriver): TourActions(appdriver).skip_tour() Navigation(appdriver).open_my_offline_page() assert Offline(appdriver).get_page_title_text() == 'Offline' assert Offline(appdriver).get_image_comparison_percents() > 0.9
所有这一切的结果是我得到了一定比例的图片相似度。它可以是您需要的那个百分比。我的测试没问题。
我无法使用 openCV 库。
因为我无法安装opencv4nodejs
您可以尝试使用 npm 模块以这种方式安装它:npm i -g opencv4nodejs
所以,我找到了比较图像的解决方案。您可以使用此代码:
/**
* Finds the a region in one image that best matches another, smaller, image.
*/
public static int[] findSubImage(BufferedImage im1, BufferedImage im2){
int w1 = im1.getWidth(); int h1 = im1.getHeight();
int w2 = im2.getWidth(); int h2 = im2.getHeight();
assert(w2 <= w1 && h2 <= h1);
// will keep track of best position found
int bestX = 0; int bestY = 0; double lowestDiff = Double.POSITIVE_INFINITY;
// brute-force search through whole image (slow...)
for(int x = 0;x < w1-w2;x++){
for(int y = 0;y < h1-h2;y++){
double comp = compareImages(im1.getSubimage(x,y,w2,h2),im2);
if(comp < lowestDiff){
bestX = x; bestY = y; lowestDiff = comp;
}
}
}
// output similarity measure from 0 to 1, with 0 being identical
System.out.println(lowestDiff + "output similarity measure from 0 to 1, with 0 being identical");
Assertions.assertTrue(lowestDiff<0.5);
// return best location
return new int[]{bestX,bestY};
}
/**
* Determines how different two identically sized regions are.
*/
public static double compareImages(BufferedImage im1, BufferedImage im2){
assert(im1.getHeight() == im2.getHeight() && im1.getWidth() == im2.getWidth());
double variation = 0.0;
for(int x = 0;x < im1.getWidth();x++){
for(int y = 0;y < im1.getHeight();y++){
variation += compareARGB(im1.getRGB(x,y),im2.getRGB(x,y))/Math.sqrt(3);
}
}
return variation/(im1.getWidth()*im1.getHeight());
}
/**
* Calculates the difference between two ARGB colours (BufferedImage.TYPE_INT_ARGB).
*/
public static double compareARGB(int rgb1, int rgb2){
double r1 = ((rgb1 >> 16) & 0xFF)/255.0; double r2 = ((rgb2 >> 16) & 0xFF)/255.0;
double g1 = ((rgb1 >> 8) & 0xFF)/255.0; double g2 = ((rgb2 >> 8) & 0xFF)/255.0;
double b1 = (rgb1 & 0xFF)/255.0; double b2 = (rgb2 & 0xFF)/255.0;
double a1 = ((rgb1 >> 24) & 0xFF)/255.0; double a2 = ((rgb2 >> 24) & 0xFF)/255.0;
// if there is transparency, the alpha values will make difference smaller
return a1*a2*Math.sqrt((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2));
}
我找到了 here。 它工作得很好,但太慢了。 如果你也不会使用openCV,你可以使用这种方式。 祝你好运。