def init_screencap_mode(cls, mode): consts = UtilConsts.ScreenCapMode cls.screencap_mode = mode if cls.screencap_mode == consts.ASCREENCAP: # Prepare for ascreencap, push the required libraries Adb.exec_out('rm /data/local/tmp/ascreencap') cpuArc = Adb.exec_out('getprop ro.product.cpu.abi').decode( 'utf-8').strip() sdkVer = int( Adb.exec_out('getprop ro.build.version.sdk').decode( 'utf-8').strip()) ascreencaplib = 'ascreencap_{}'.format(cpuArc) if sdkVer in range(21, 26) and os.path.isfile(ascreencaplib): Adb.cmd( 'push {} /data/local/tmp/ascreencap'.format(ascreencaplib)) else: Logger.log_warning( 'No suitable version of aScreenCap lib is available locally, using ascreencap_local...' ) if os.path.isfile('ascreencap_local'): Adb.cmd('push ascreencap_local /data/local/tmp/ascreencap') else: Logger.log_error( 'File "ascreencap_local" not found. Please download the appropriate version of aScreenCap for your device from github.com/ClnViewer/Android-fast-screen-capture and save it as "ascreencap_local"' ) Logger.log_warning( 'Since aScreenCap is not ready, falling back to normal adb screencap' ) Utils.useAScreenCap = False Adb.shell('chmod 0777 /data/local/tmp/ascreencap')
def update_screen(): """Uses ADB to pull a screenshot of the device and then read it via CV2 and then returns the read image. The image is in a grayscale format. Returns: image: A CV2 image object containing the current device screen. """ global screen screen = None while screen is None: if Adb.legacy: screen = cv2.imdecode(numpy.fromstring(Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"),dtype=numpy.uint8),0) else: screen = cv2.imdecode(numpy.fromstring(Adb.exec_out('screencap -p'), dtype=numpy.uint8), 0)
def get_color_screen(): """Uses ADB to pull a screenshot of the device and then read it via CV2 and then returns the read image. The image is in a BGR format. Returns: image: A CV2 image object containing the current device screen. """ color_screen = None while color_screen is None: if Adb.legacy: color_screen = cv2.imdecode(numpy.fromstring(Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"),dtype=numpy.uint8), 1) else: color_screen = cv2.imdecode(numpy.fromstring(Adb.exec_out('screencap -p'), dtype=numpy.uint8), 1) return color_screen
def find_siren_elites(cls): # XXX: This should be pulled into its own method at some point. color_screen = None while color_screen is None: if Adb.legacy: color_screen = cv2.imdecode( numpy.fromstring( Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"), dtype=numpy.uint8), 1) else: color_screen = cv2.imdecode( numpy.fromstring(Adb.exec_out('screencap -p'), dtype=numpy.uint8), 1) image = cv2.cvtColor(color_screen, cv2.COLOR_BGR2HSV) # We use this primarily to pick out elites from event maps. Depending on the event, this may need to be updated with additional masks. lower_red = numpy.array([170, 210, 180]) upper_red = numpy.array([180, 255, 255]) mask = cv2.inRange(image, lower_red, upper_red) ret, thresh = cv2.threshold(mask, 50, 255, cv2.THRESH_BINARY) # Build a structuring element to combine nearby contours together. rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25)) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, rect_kernel) im, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = list(filter(lambda x: cv2.contourArea(x) > 3000, contours)) locations = [] for contour in contours: hull = cv2.convexHull(contour) M = cv2.moments(hull) x = round(M['m10'] / M['m00']) y = round(M['m01'] / M['m00']) approx = cv2.approxPolyDP(hull, 0.04 * cv2.arcLength(contour, True), True) bound_x, bound_y, width, height = cv2.boundingRect(approx) aspect_ratio = width / float(height) # Avoid clicking on areas outside of the grid, filter out non-Siren matches (non-squares) if y > 160 and y < 938 and x > 180 and x < 1790 and len( approx) == 4 and aspect_ratio >= 1.5: locations.append([x, y]) return cls.filter_similar_coords(locations)
def update_screen(): """Uses ADB to pull a screenshot of the device and then read it via CV2 and then returns the read image. The image is in a grayscale format. Returns: image: A CV2 image object containing the current device screen. """ global screen screen = None while screen is None: if Adb.legacy: screen = cv2.imdecode( numpy.fromstring( Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"), dtype=numpy.uint8), 0) elif not Utils.useAScreenCap: screen = cv2.imdecode( numpy.fromstring(Adb.exec_out('screencap -p'), dtype=numpy.uint8), 0) else: start_time = time.perf_counter() raw_compressed_data = Utils.reposition_byte_pointer( Adb.exec_out( '/data/local/tmp/ascreencap --pack 2 --stdout')) compressed_data_header = numpy.frombuffer( raw_compressed_data[0:20], dtype=numpy.uint32) if compressed_data_header[0] != 828001602: compressed_data_header = compressed_data_header.byteswap() if compressed_data_header[0] != 828001602: Logger.log_error( 'If error persists, disable aScreenCap and report traceback' ) raise Exception( 'aScreenCap header verification failure, corrupted image received. HEADER IN HEX = {}' .format(compressed_data_header.tobytes().hex())) uncompressed_data_size = compressed_data_header[1].item() screen = cv2.imdecode( numpy.frombuffer(lz4.block.decompress( raw_compressed_data[20:], uncompressed_size=uncompressed_data_size), dtype=numpy.uint8), 0) elapsed_time = time.perf_counter() - start_time Logger.log_debug("aScreenCap took {} ms to complete.".format( '%.2f' % (elapsed_time * 1000)))
def update_screen(): """Uses ADB to pull a screenshot of the device and then read it via CV2 and then returns the read image. Returns: image: A CV2 image object containing the current device screen. """ decoded = None while decoded is None: decoded = cv2.imdecode( numpy.fromstring( Adb.exec_out('screencap -p'), dtype=numpy.uint8), 0) return decoded
def update_screen(cls, color=0): """Uses ascreencap or ADB depending on cls.emulator the to pull a screenshot of the device and then read it via CV2 and then returns the read image. The image is in a grayscale or BGR format. Args: color(boolean) by default 0 for grayscale, 1 outputs BGR image Returns: image: A CV2 image object containing the current device screen. """ start_time_total = time.time() global screen screen = None while screen is None: #ascreencap supported for Memu and BlueStacks only if cls.emulator == 'Memu': Adb.exec_out( '/storage/emulated/legacy/Download/ascreencap -f /storage/emulated/legacy/Download/screenshot.bmp' ) if re.search('1920x1080|1080x1920', cls.resolution): screen = cv2.imread(cls.sharedfolder + "screenshot.bmp", color) else: screen = cv2.resize( cv2.imread(cls.sharedfolder + "screenshot.bmp", color), (1920, 1080)) elif cls.emulator == 'BlueStacks': Adb.exec_out( '/storage/emulated/0/windows/BstSharedFolder/ascreencap -f /storage/emulated/0/windows/BstSharedFolder/screenshot.bmp' ) if re.search('1920x1080|1080x1920', cls.resolution): screen = cv2.imread(cls.sharedfolder + "screenshot.bmp", color) else: screen = cv2.resize( cv2.imread(cls.sharedfolder + "screenshot.bmp", color), (1920, 1080)) else: #defaults to adb screencap if Adb.legacy: screen = cv2.imdecode( numpy.fromstring( Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"), dtype=numpy.uint8), 0) else: screen = cv2.imdecode( numpy.fromstring(Adb.exec_out('screencap -p'), dtype=numpy.uint8), 0) end_time_total = time.time() Logger.log_debug("update_screen took: " + str(end_time_total - start_time_total)[:5])
Logger.log_info("Enabled debugging.") Logger.enable_debugging(Logger) if args.legacy: Logger.log_info("Enabled sed usage.") Adb.enable_legacy(Adb) script = ALAuto(config) script.run_update_check() Adb.service = config.network['service'] Adb.device = '-d' if (Adb.service == 'PHONE') else '-e' adb = Adb() if adb.init(): Logger.log_msg('Successfully connected to the service.') output = Adb.exec_out('wm size').decode('utf-8').strip() if not re.search('1920x1080|1080x1920', output): Logger.log_error("Resolution is not 1920x1080, please change it.") sys.exit() Utils.assets = config.assets['server'] else: Logger.log_error('Unable to connect to the service.') sys.exit() try: while True: Utils.update_screen() # temporal solution to event alerts
import cv2 from util.adb import Adb from PIL import Image # A short script to take screen captures to contribute to the 720p bot version # Works with Memu by default, refer to update_screen in utils.py to make it work with Bluestacks # The output should be a 1080p upscaled version of the 720p screenshot Adb.service = '192.168.0.17:5555' Adb.tcp = False adb = Adb() adb.exec_out( '/storage/emulated/legacy/Download/ascreencap -f /storage/emulated/legacy/Download/screenshot.bmp' ) screen = cv2.resize( cv2.imread("C:\\Users\\Michel14\\Downloads\\MEmu Download\\screenshot.bmp", 1), (1920, 1080)) cv2.imwrite('screenshot.png', screen)
def update_screen(cls): """Uses ADB to pull a screenshot of the device and then read it via CV2 and then stores the images in grayscale and color to screen and color_screen, respectively. Returns: image: A CV2 image object containing the current device screen. """ consts = UtilConsts.ScreenCapMode global screen screen = None color_screen = None while color_screen is None: if Adb.legacy: color_screen = cv2.imdecode( numpy.fromstring(Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"), dtype=numpy.uint8), cv2.IMREAD_COLOR) else: if cls.screencap_mode == consts.SCREENCAP_PNG: start_time = time.perf_counter() color_screen = cv2.imdecode(numpy.frombuffer(Adb.exec_out('screencap -p'), dtype=numpy.uint8), cv2.IMREAD_COLOR) elapsed_time = time.perf_counter() - start_time Logger.log_debug("SCREENCAP_PNG took {} ms to complete.".format('%.2f' % (elapsed_time * 1000))) elif cls.screencap_mode == consts.SCREENCAP_RAW: start_time = time.perf_counter() pixel_size = 4 byte_arr = Adb.exec_out('screencap') header_format = 'III' header_size = struct.calcsize(header_format) if len(byte_arr) < header_size: continue header = struct.unpack(header_format, byte_arr[:header_size]) width = header[0] height = header[1] if len(byte_arr) != header_size + width * height * pixel_size: continue tmp = numpy.frombuffer(byte_arr, dtype=numpy.uint8, count=width * height * 4, offset=header_size) rgb_img = tmp.reshape((height, width, -1)) color_screen = cv2.cvtColor(rgb_img, cv2.COLOR_RGB2BGR) elapsed_time = time.perf_counter() - start_time Logger.log_debug("SCREENCAP_RAW took {} ms to complete.".format('%.2f' % (elapsed_time * 1000))) elif cls.screencap_mode == consts.ASCREENCAP: start_time = time.perf_counter() raw_compressed_data = Utils.reposition_byte_pointer( Adb.exec_out('/data/local/tmp/ascreencap --pack 2 --stdout')) compressed_data_header = numpy.frombuffer(raw_compressed_data[0:20], dtype=numpy.uint32) if compressed_data_header[0] != 828001602: compressed_data_header = compressed_data_header.byteswap() if compressed_data_header[0] != 828001602: Logger.log_error('If error persists, disable aScreenCap and report traceback') raise Exception( 'aScreenCap header verification failure, corrupted image received. HEADER IN HEX = {}'.format( compressed_data_header.tobytes().hex())) uncompressed_data_size = compressed_data_header[1].item() color_screen = cv2.imdecode(numpy.frombuffer( lz4.block.decompress(raw_compressed_data[20:], uncompressed_size=uncompressed_data_size), dtype=numpy.uint8), cv2.IMREAD_COLOR) elapsed_time = time.perf_counter() - start_time Logger.log_debug("aScreenCap took {} ms to complete.".format('%.2f' % (elapsed_time * 1000))) else: raise Exception('Unknown screencap mode') screen = cv2.cvtColor(color_screen, cv2.COLOR_BGR2GRAY) cls.color_screen = color_screen cls.screen = screen
if args.legacy: Logger.log_info("Enabled sed usage.") Adb.enable_legacy(Adb) script = ALAuto(config) script.run_update_check() Adb.service = config.network['service'] Adb.tcp = False if (Adb.service.find(':') == -1) else True adb = Adb() if adb.init(): Logger.log_msg( 'Successfully connected to the service with transport_id({}).'.format( Adb.transID)) config.resolution = Adb.exec_out('wm size').decode('utf-8').strip() Logger.log_debug('wm size request returned ' + str(config.resolution)) # check supported resolution and setting asset path accordingly if re.search('1920x1080|1080x1920', config.resolution): Utils.assets = config.assets['server'] + '/1080' elif re.search('1280x720|720x1280', config.resolution): Utils.assets = config.assets['server'] + '/720' else: Logger.log_error( "Resolution is not 1920x1080 nor 1280x720, please change it.") sys.exit() else: Logger.log_error('Unable to connect to the service.') sys.exit()
if args.legacy: Logger.log_info("Enabled sed usage.") Adb.enable_legacy(Adb) script = ALAuto(config) script.run_update_check() Adb.service = config.network['service'] Adb.tcp = False if (Adb.service.find(':') == -1) else True adb = Adb() if adb.init(): Logger.log_msg( 'Successfully connected to the service with transport_id({}).'.format( Adb.transID)) output = Adb.exec_out('wm size').decode('utf-8').strip() if not re.search('1920x1080|1080x1920', output): Logger.log_error("Resolution is not 1920x1080, please change it.") sys.exit() Utils.assets = config.assets['server'] # aScreenCap init useAScreenCap = config.screenshot['useAScreenCap'] Utils.useAScreenCap = useAScreenCap if useAScreenCap: # Prepare for ascreencap, push the required libraries Adb.exec_out('rm /data/local/tmp/ascreencap') cpuArc = Adb.exec_out('getprop ro.product.cpu.abi').decode(
def update_screen(cls, color=0): """Uses ascreencap or ADB depending on cls.emulator the to pull a screenshot of the device and then read it via CV2 and then returns the read image. The image is in a grayscale or BGR format. Args: color(boolean) by default 0 for grayscale, 1 outputs BGR image Returns: image: A CV2 image object containing the current device screen. """ start_time_total = time.time() global screen screen = None method = 'shared folder ' + cls.emulator while screen is None: #ascreencap supported for Memu and BlueStacks only if cls.emulator == 'Memu': Adb.exec_out( '/storage/emulated/legacy/Download/ascreencap -f /storage/emulated/legacy/Download/screenshot.bmp' ) if re.search('1920x1080|1080x1920', cls.resolution): screen = cv2.imread(cls.sharedfolder + "screenshot.bmp", color) else: screen = cv2.resize( cv2.imread(cls.sharedfolder + "screenshot.bmp", color), (1920, 1080)) elif cls.emulator == 'BlueStacks': Adb.exec_out( '/storage/emulated/0/windows/BstSharedFolder/ascreencap -f /storage/emulated/0/windows/BstSharedFolder/screenshot.bmp' ) if re.search('1920x1080|1080x1920', cls.resolution): screen = cv2.imread(cls.sharedfolder + "screenshot.bmp", color) else: screen = cv2.resize( cv2.imread(cls.sharedfolder + "screenshot.bmp", color), (1920, 1080)) #defaults to using stdout methods elif useAScreenCap == True: method = 'Ascreencap' raw_compressed_data = Adb.exec_out( '/data/local/tmp/ascreencap --pack 2 --stdout') compressed_data_header = numpy.frombuffer( raw_compressed_data[0:20], dtype=numpy.uint32) if compressed_data_header[0] != 828001602: compressed_data_header = compressed_data_header.byteswap() if compressed_data_header[0] != 828001602: raise Exception( 'aScreenCap header verification failure, corrupted image received' ) uncompressed_data_size = compressed_data_header[1].item() screen = cv2.imdecode( numpy.frombuffer(lz4.block.decompress( raw_compressed_data[20:], uncompressed_size=uncompressed_data_size), dtype=numpy.uint8), color) else: method = 'Adb screencap' if Adb.legacy: screen = cv2.imdecode( numpy.fromstring( Adb.exec_out(r"screencap -p | sed s/\r\n/\n/"), dtype=numpy.uint8), color) else: screen = cv2.imdecode( numpy.fromstring(Adb.exec_out('screencap -p'), dtype=numpy.uint8), color) end_time_total = time.time() Logger.log_debug("update_screen with method " + method + " took: " + str(end_time_total - start_time_total)[:5])
if args.legacy: Logger.log_info("Enabled sed usage.") Adb.enable_legacy(Adb) script = ALAuto(config) script.run_update_check() Adb.service = config.network['service'] Adb.device = '-d' if (Adb.service == 'PHONE') else '-e' adb = Adb() if adb.init(): Logger.log_msg('Successfully connected to the service.') res = ['1920x1080', '1080x1920'] if Adb.exec_out('wm size').decode('utf-8').strip()[15:] not in res: Logger.log_error("Resolution is not 1920x1080, please change it.") sys.exit() else: Logger.log_error('Unable to connect to the service.') sys.exit() while True: Utils.update_screen() # temporal solution to event alerts if not Utils.find("menu/button_battle"): Utils.touch_randomly(Region(54, 57, 67, 67)) Utils.script_sleep(1) continue if Utils.find("commission/alert_completed"):