【问题标题】:Convert iterator objects from findAll to images in Sikuli after sorting排序后将迭代器对象从findAll转换为Sikuli中的图像
【发布时间】:2014-09-03 17:52:48
【问题描述】:

所以我在与 Sikuli 合作时遇到了问题。存在图像多次出现的情况。要获取所有这些,您可以简单地执行 findAll,但它将每个图像保存为某种对象,而不是图像。我知道您可以使用 getLastMatches() 获取图像,但我想先对其进行排序。所以这是我得到的代码,它可以抓取所有图像并对其进行排序。我在Sikuli文档上找到了一些信息

def by_y(match):
  return match.y

icons = findAll(image)
sorted_icons = sorted(icons, key=by_y)

不过,问题在于 sorted_icons 包含一堆可迭代对象(至少我看到它们是这样称呼的),而不是图像。有没有办法在保持新列表排序的同时恢复到图像?使用 getLastMatches() 给出原始未排序列表的列表。

另外,它是 Sikuli 1.0.1。

谢谢。

这应该说明问题(希望如此)。为了按图像的 y 值对图像进行排序,我必须使用 findAll() 操作(如果有一种方法可以在不使用 find 的情况下执行此操作,请分享)。但是,这会将图像从字符串转换,即:

"imagename.png"

进入...不管这是什么(匹配?):

M[8,1045 37x28]@S(S(0)[0,0 1920x1080]) S:1.00 Center:26,1059

self.assets.getimage(image) 函数需要一个字符串,但是(所以 imagename.png)而不是你使用 find 得到的时髦的东西。

def exampleMethod(image, dx=0, dy=0):
    click(Pattern(self.assets.getimage(image)).targetOffset(dx, dy))

def by_y(match):
  return match.y

image = "imagename.png"
icons = findAll(image)
sorted_icons = sorted(image, key=by_y)

exampleMethod(sorted_icons[0])

因此,我需要两件事中的一件:

  1. 一种在排序后将查找对象转换回字符串的方法
  2. 一种按图像 y 值对图像进行排序,同时将图像保留为字符串的方法

希望这会有所帮助。

【问题讨论】:

  • 我问你想对图像做什么? findfindAll 操作使用模式/图片/屏幕截图或字符串作为输入类型并返回 (a) 匹配对象,通过它您可以完成几乎任何 Sikuli 必须提供的...跨度>
  • 有很多预先存在的方法需要图像而不是图案。他们每个人都使用 find 方法(以及类似于 find 的自建方法)。我可以加入一些 if 语句来处理这个问题,但这将是很多我不想做的改变。因此,我希望能够将它们转换回图像并将它们发送到方法
  • 我不确定我是否清楚 -- 图像和图案有什么区别?在上面的示例中,icons = findAll(image) 这里的“图像”是 Pattern 类型。相比之下,如果您说 `iconNames = findAll("IconTitle"),那么 IconTitle 将是 String 类型。 findAll() 操作接受的唯一两种类型是 Pattern 和 String。你的意思是图案和图像是同一个东西吗?
  • 对不起,“图像”是指我猜的字符串。所以在我的代码中,我使用了 findAll 方法,它将字符串转换为......无论它变成什么。之后我必须调用的方法也包含 find 方法。但是,由于图像不再是图像/字符串,所以 find 方法不会接受它。换句话说,我正在调用的方法正在尝试这样做:find(findAll(image)) 并且它不喜欢那样。
  • 没有看到你的代码,很难说,但你确定你真的需要第二次查找操作吗?无论是您最初寻找的字符串还是模式/图片,通常 find() 只是您想做的任何其他事情的初步。而且因为你已经找到了一次,你可以跳过第二次找到它,直接去做你想做的任何事情。你能发布一些代码吗?

标签: sorting jython sikuli


【解决方案1】:

只是一个简短的信息。 JePySi 不处理图标/图像的动态分配。这需要使用 Sikuli 功能完全实现。所以 autoKarma 是对的,self.assets.getImage() 在这种情况下是没有用的,因为它只访问仅按名称寻址的预注册图像。因此只有字符串操作。

干杯, Alex - 我写了 JePySi :-)

【讨论】:

  • 哇,您是使用 JePySi 还是实际编写的?就像 JePySi 的开发者一样?大声笑你知道这样做的好方法吗?从技术上讲,我可以在 try/except 语句中放置一个 click(match),并在其中使用命令“assert testcontext.browser.failed(...)”,这样仍然可以记录它。如果能找到解决办法就好了。
【解决方案2】:

我不确定这会具体回答您的问题,但我认为有一种更直接的方法可以实现您的目的。

您的exampleMethod() 是对内置click() 函数的重申--

click() 将单击模式、字符串、位置、区域或(对于这个问题最重要的是)匹配就好,因此您实际上不需要返回图像即可单击它。您也不需要 self.assets.getimage() 来访问要单击的图像。 click() 函数首先隐式执行 find() 操作,然后单击它找到的任何内容。由于您将单击 Match 对象,因此它只会转到匹配对象提供的坐标并单击这些坐标。

另外,默认的.targetOffset 是 (0, 0)(这意味着它将点击找到的图像的中心)。因此,您可能不需要在 exampleMethod() 中预先定义为 0。

总之,如果一个页面上有同一张图片的多个相同副本,并且您想点击每个副本以顺着屏幕向下移动,您可以执行以下操作:

icons = list([x for x in findAll(image)]) #cast matches from the findAll() into a list 
sorted_icons = sorted(icons, key=by_y) #note 'icons' here and not 'image'
for icon in sorted_icons:  
    click(icon)
    #anything else you want to do with them

另一种方法,不使用 Python 的列表解析(以防你不熟悉):

findAll(images)
icons = getLastMatches()
sorted_icons = sorted(icons, key=by_y)
listOfSortedIcons = []
while sorted_icons.hasNext():
    listOfSortedIcons.append(sorted_icons.next())
for icon in listOfSortedIcons:
    click(icon)
    #whatever else...

【讨论】:

  • 抱歉,里面应该是图标。但我正在使用 Jepysi(Ruby+Cucumber 的 Python 版本)。我只是没有说明它,因为无论如何似乎没有人知道它。它应该是 click() 的复制品。但是,在它的方法中,它使用了“name.endswith()”方法,该方法需要一个字符串。因此,必须发送一个字符串,而不是一个匹配项。我想我的例子可能不是最有效的。
  • “getimage(image)”方法使用endswith(),由于它与特征文件中的资产有联系,我无法删除它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
相关资源
最近更新 更多