在雷電模擬器內指定區域查詢回復圖示,對映到螢幕畫素點選

yyxgs發表於2020-11-28

這是使用雷電模擬器開啟小米手機吧,我想點選回帖圖示,本來很簡單,做一個圖示的識別就完事了,可是呢,這個圖示很容易被相似的圖示給識別到了,例如左邊的分享圖示,做太精確的識別必然更耗時間,而且還容易出錯。所以需要把查詢的區域固定到模擬器中間部分。

那麼第一步,先找到模擬器的位置,例如用Home圖示來判斷:

	public Location 查詢雷電模擬器的主頁圖示()
	{
		// 截圖
		value.sys.screenCapture();	

		Location location = new Location(-1, -1);

		// 讀取圖片到LortImage物件
		LortImage lortImage = ReadImage.getImageInArrayLort_COLUMN(value.path.imagePath, 0, 0, 1919, 1079);

		IndexFindColor indexFindColor = new IndexFindColor(new Location(850,946), ColorStr.reverseColorString("131313"), 10, 10, 10);
		indexFindColor.add(850,940, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(850,951, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(849,994, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(849,989, ColorStr.reverseColorString("131313"));
		indexFindColor.add(849,985, ColorStr.reverseColorString("131313"));
		indexFindColor.add(852,981, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(856,981, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(846,897, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(854,896, ColorStr.reverseColorString("131313"));

		location = indexFindColor.find(lortImage, indexFindColor);

		return location;
	}

找到模擬器圖示位置之後,就可以確定這個模擬器左上角和右下角座標,也就是這個模擬器螢幕大小:

Location 主頁圖示 = value.identification.查詢雷電模擬器的主頁圖示();
LocationRegion 模擬器螢幕區域 = new LocationRegion(主頁圖示, -568, -905, -17, 75);
模擬器螢幕區域.println();

輸出結果:
10, 44 561, 1024

然後讓指令碼生成這個區域的影像:

然後這個圖示應該在這個範圍內去查詢:

 識別帖子圖示:

public Location 查詢帖子的回覆圖示()
{
	// 已經使用模擬器區域截圖, 所以也不可以使用整個螢幕截圖

	Location location = new Location(-1, -1);

	// 讀取圖片到LortImage物件
	LortImage lortImage = ReadImage.getImageInArrayLort_COLUMN(value.path.imagePath, new Location(10, 44).calcMove(195, -44), new Location(561, 1024).calcMove(309, 935));

	IndexFindColor indexFindColor = new IndexFindColor(new Location(530,391), ColorStr.reverseColorString("545151"), 30);
	indexFindColor.add(533,390, ColorStr.reverseColorString("FFFFFF"));
	indexFindColor.add(540,382, ColorStr.reverseColorString("545151"));
	indexFindColor.add(548,391, ColorStr.reverseColorString("FFFFFF"));
	indexFindColor.add(551,392, ColorStr.reverseColorString("585555"));
	indexFindColor.add(537,402, ColorStr.reverseColorString("545151"));
	indexFindColor.add(544,402, ColorStr.reverseColorString("545151"));
	indexFindColor.add(538,392, ColorStr.reverseColorString("545151"));
	indexFindColor.add(540,393, ColorStr.reverseColorString("585555"));
	indexFindColor.add(543,392, ColorStr.reverseColorString("545151"));

	location = indexFindColor.find(lortImage, indexFindColor);

	return location;
}

現在,回覆的圖示的確是找到了,但是這樣一繞,對應的複雜的工作就隨之而來了。影像區域變化:整個電腦螢幕區域 -> 模擬器螢幕區域 -> 帖子中間區域,所以在找到回覆圖示後,又要一直把之前所有偏移的座標重新加上,才能得到準確的整個螢幕的座標,這樣去點選才能對應到這個圖示上去。

所以:

Location 主頁圖示 = value.identification.查詢雷電模擬器的主頁圖示();
LocationRegion 模擬器螢幕區域 = new LocationRegion(主頁圖示, -568, -905, -17, 75);

value.sys.模擬器區域截圖(模擬器螢幕區域);
	
Location 回覆圖示 = value.identification.查詢帖子的回覆圖示();
回覆圖示.move(205, 0); // 從帖子中間部分的左上角偏移到模擬器左上角, 205, 0的計算方法: new Location(10, 44).calcMove(195, -44), 相加 = 205, 0
回覆圖示.move(模擬器螢幕區域.getStartLocation());
回覆圖示.println();

現在這個圖示我們們就可以去點選了,它就是回覆圖示在螢幕中的準確位置。

接下來封裝為一個類:

/**
 * 模擬器
 */
public class Emulator
{
	public Value value;
	
	public Location 主頁圖示;
	public LocationRegion 螢幕區域範圍;
	
	public Emulator(Value value)
	{
		this.value = value;
		
		主頁圖示 = 查詢雷電模擬器的主頁圖示();
		螢幕區域範圍 = new LocationRegion(主頁圖示, -568, -905, -17, 75);
	}
	
	public void 回覆帖子()
	{
		Location location = 查詢帖子的回覆圖示();
		
		if (location.getBooleanValue() == true)
		{
			value.rp.tapLeft(location);
		}
		else
		{
			System.out.println("失敗...沒有找到回覆圖示");
		}
	}
	
	public Location 查詢帖子的回覆圖示()
	{
		模擬器區域截圖();

		Location location = new Location(-1, -1);

		// 讀取圖片到LortImage物件
		LortImage lortImage = ReadImage.getImageInArrayLort_COLUMN(value.path.imagePath, new Location(10, 44).calcMove(195, -44), new Location(561, 1024).calcMove(309, 935));

		IndexFindColor indexFindColor = new IndexFindColor(new Location(530,391), ColorStr.reverseColorString("545151"), 30);
		indexFindColor.add(533,390, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(540,382, ColorStr.reverseColorString("545151"));
		indexFindColor.add(548,391, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(551,392, ColorStr.reverseColorString("585555"));
		indexFindColor.add(537,402, ColorStr.reverseColorString("545151"));
		indexFindColor.add(544,402, ColorStr.reverseColorString("545151"));
		indexFindColor.add(538,392, ColorStr.reverseColorString("545151"));
		indexFindColor.add(540,393, ColorStr.reverseColorString("585555"));
		indexFindColor.add(543,392, ColorStr.reverseColorString("545151"));

		location = indexFindColor.find(lortImage, indexFindColor);
		
		if (location.getBooleanValue() == true)
		{
			location.move(new Location(10, 44).calcMove(195, -44));
			location.move(螢幕區域範圍.getStartLocation());
		}

		return location;
	}
	
	private void 模擬器區域截圖()
	{
		value.rp.screenCaptureRegion(螢幕區域範圍, value.path.imagePath);
	}
	
	private Location 查詢雷電模擬器的主頁圖示()
	{
		// 截圖
		value.sys.screenCapture();

		// 讀取圖片到LortImage物件
		LortImage lortImage = ReadImage.getImageInArrayLort_COLUMN(value.path.imagePath, 0, 0, 1919, 1079);

		IndexFindColor indexFindColor = new IndexFindColor(new Location(850,946), ColorStr.reverseColorString("131313"), 10, 10, 10);
		indexFindColor.add(850,940, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(850,951, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(849,994, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(849,989, ColorStr.reverseColorString("131313"));
		indexFindColor.add(849,985, ColorStr.reverseColorString("131313"));
		indexFindColor.add(852,981, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(856,981, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(846,897, ColorStr.reverseColorString("FFFFFF"));
		indexFindColor.add(854,896, ColorStr.reverseColorString("131313"));

		主頁圖示 = indexFindColor.find(lortImage, indexFindColor);

		return 主頁圖示;
	}
}

使用:

// 建立模擬器
Emulator emulator = new Emulator(value);
	
// 回覆帖子
emulator.回覆帖子();

完成。

相關文章