Skip to content

Commit 7dd5d2c

Browse files
author
gabriel-archanjo
committed
new method to search multiple occurrences of the same UI element in the screen
1 parent 81ffa02 commit 7dd5d2c

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

src/main/java/dev/botcity/framework/bot/DesktopBot.java

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,16 @@ public void click() {
616616
sleep(sleepAfterAction);
617617
}
618618

619+
/**
620+
* Click in last found UI element.
621+
*/
622+
public void setCurrentElement(UIElement el) {
623+
this.x = el.getX();
624+
this.y = el.getY();
625+
this.visualElem = el.getImage();
626+
this.lastElement = el;
627+
}
628+
619629
/**
620630
* Right Click in last found UI element.
621631
*/
@@ -1698,4 +1708,159 @@ private Point getElementCoordsCentered(MarvinImage sub, double matching, boolean
16981708

16991709
return bestSegment;
17001710
}
1711+
1712+
public List<UIElement> findAllUntil(String elementId, double elementMatching, int maxWaitingTime) {
1713+
return findAllUntil(elementId, getImageFromMap(elementId), null, null, null, null, null, elementMatching, maxWaitingTime);
1714+
}
1715+
1716+
public List<UIElement> findAllUntil
1717+
(
1718+
String elementId,
1719+
MarvinImage visualElem,
1720+
Integer startX,
1721+
Integer startY,
1722+
Integer searchWindowWidth,
1723+
Integer searchWindowHeight,
1724+
Integer threshold,
1725+
Double elementMatching,
1726+
int maxWaitingTime
1727+
) {
1728+
long startTime = System.currentTimeMillis();
1729+
while(true) {
1730+
1731+
if(System.currentTimeMillis() - startTime > maxWaitingTime) {
1732+
return null;
1733+
}
1734+
sleep(100);
1735+
screenshot();
1736+
1737+
Point p=null;
1738+
1739+
startX = (startX != null ? startX : 0);
1740+
startY = (startY != null ? startY : 0);
1741+
searchWindowWidth = (searchWindowWidth != null ? searchWindowWidth : screen.getWidth());
1742+
searchWindowHeight = (searchWindowHeight != null ? searchWindowHeight : screen.getHeight());
1743+
1744+
List<UIElement> elements=null;
1745+
if(threshold != null) {
1746+
1747+
1748+
1749+
MarvinImage screenCopy = screen.clone();
1750+
thresholding(screenCopy, threshold);
1751+
1752+
MarvinImage visualElemCopy = visualElem.clone();
1753+
thresholding(visualElemCopy, threshold);
1754+
1755+
1756+
1757+
//p = getElementCoords(visualElemCopy, screenCopy, startX, startY, searchWindowWidth, searchWindowHeight, elementMatching, best);
1758+
1759+
elements = findAllSubimages(visualElemCopy, screenCopy, startX, startY, searchWindowWidth, searchWindowHeight, elementMatching);
1760+
1761+
1762+
1763+
if(debug) {
1764+
long timestamp = System.currentTimeMillis();
1765+
String match = (elements.isEmpty() ? "false" : "true");
1766+
MarvinImageIO.saveImage(screen, "./debug/"+timestamp+"_screen"+"_"+elementId+"_"+match+".png");
1767+
MarvinImageIO.saveImage(visualElem, "./debug/"+timestamp+"_"+elementId+"_"+match+".png");
1768+
MarvinImageIO.saveImage(screenCopy, "./debug/"+timestamp+"_screen_bw_"+elementId+"_"+match+".png");
1769+
MarvinImageIO.saveImage(visualElemCopy, "./debug/"+timestamp+"_"+elementId+"_bw"+"_"+match+".png");
1770+
}
1771+
1772+
} else {
1773+
elements = findAllSubimages(visualElem, screen, startX, startY, searchWindowWidth, searchWindowHeight, elementMatching);
1774+
1775+
if(debug) {
1776+
long timestamp = System.currentTimeMillis();
1777+
String match = (elements.isEmpty() ? "false" : "true");
1778+
MarvinImageIO.saveImage(screen, "./debug/"+timestamp+"_screen"+"_"+elementId+"_"+match+".png");
1779+
MarvinImageIO.saveImage(visualElem, "./debug/"+timestamp+"_"+elementId+"_"+match+".png");
1780+
}
1781+
}
1782+
1783+
// Matched?
1784+
if(elements != null && !elements.isEmpty()) {
1785+
return elements;
1786+
}
1787+
}
1788+
}
1789+
1790+
1791+
1792+
public List<UIElement> findAllSubimages
1793+
(
1794+
MarvinImage subimage,
1795+
MarvinImage imageIn,
1796+
int startX,
1797+
int startY,
1798+
int searchWindowWidth,
1799+
int searchWindowHeight,
1800+
Double similarity
1801+
) {
1802+
List<UIElement> elements = new ArrayList<UIElement>();
1803+
int subImagePixels = subimage.getWidth()*subimage.getHeight();
1804+
boolean[][] processed=new boolean[imageIn.getWidth()][imageIn.getHeight()];
1805+
1806+
int r1,g1,b1,r2,g2,b2;
1807+
// Full image
1808+
mainLoop:for(int y=startY; y<startY+searchWindowHeight; y++){
1809+
for(int x=startX; x<startX+searchWindowWidth; x++){
1810+
1811+
if(processed[x][y]){
1812+
continue;
1813+
}
1814+
1815+
int notMatched=0;
1816+
boolean match=true;
1817+
int colorThreshold = (int)(255 * colorSensibility);
1818+
1819+
// subimage
1820+
if(y+subimage.getHeight() < imageIn.getHeight() && x+subimage.getWidth() < imageIn.getWidth()){
1821+
1822+
1823+
outerLoop:for(int i=0; i<subimage.getHeight(); i++){
1824+
for(int j=0; j<subimage.getWidth(); j++){
1825+
1826+
if(processed[x+j][y+i]){
1827+
match=false;
1828+
break outerLoop;
1829+
}
1830+
1831+
r1 = imageIn.getIntComponent0(x+j, y+i);
1832+
g1 = imageIn.getIntComponent1(x+j, y+i);
1833+
b1 = imageIn.getIntComponent2(x+j, y+i);
1834+
1835+
r2 = subimage.getIntComponent0(j, i);
1836+
g2 = subimage.getIntComponent1(j, i);
1837+
b2 = subimage.getIntComponent2(j, i);
1838+
1839+
if
1840+
(
1841+
Math.abs(r1-r2) > colorThreshold ||
1842+
Math.abs(g1-g2) > colorThreshold ||
1843+
Math.abs(b1-b2) > colorThreshold
1844+
){
1845+
notMatched++;
1846+
1847+
if(notMatched > (1-similarity)*subImagePixels){
1848+
match=false;
1849+
break outerLoop;
1850+
}
1851+
}
1852+
}
1853+
}
1854+
} else{
1855+
match=false;
1856+
}
1857+
1858+
if(match){
1859+
elements.add(new UIElement(x,y, subimage));
1860+
}
1861+
}
1862+
}
1863+
1864+
return elements;
1865+
}
17011866
}

src/main/java/dev/botcity/framework/bot/UIElement.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ public class UIElement {
1515
width,
1616
height;
1717

18+
public UIElement() {}
19+
20+
public UIElement(Integer x, Integer y, MarvinImage image) {
21+
super();
22+
this.image = image;
23+
this.x = x;
24+
this.y = y;
25+
this.width = image.getWidth();
26+
this.height = image.getHeight();
27+
}
1828
public MarvinImage getImage() {
1929
return image;
2030
}

0 commit comments

Comments
 (0)