def __check_output_name(self, name): ''' Verify that the name is free or if the number of screenshots does not exceed 999. Parameters ---------- name: str The name of the picture if given. Otherwise the name will be such as << imagerobot-screenshot-XXX.png >>. Raises ------ RobotException Throw an error if the user launching the function cannot write on disk. Throw an error if the user already has 999 sreenshots in the repository. Throw an error if the user set a name in a wrong format without finishing by << .png >> nor << .jpg >>. Return ------ output_name: str The future name of the screenshot if the image is found. ''' output_name = self.screenshot_name output_number = "000" if os.path.isfile(output_name + "-001.png") and name is None: for i in range(1, 1001): if i < 10: output_number = "00" + str(i) elif i < 100: output_number = "0" + str(i) else: output_number = str(i) if i == 1000: RobotException().too_many_screenshots_exception() if not os.path.isfile(output_name + "-" + output_number + ".png"): output_name = output_name + "-" + output_number + ".png" break else: output_name = self.screenshot_name + "-001.png" if name is not None: if str(name[-4:]).lower() == ".png" or str( name[-4:]).lower() == ".jpg": output_name = str(name) else: RobotException().image_format_exception() return output_name
def __prepare_output_image(self, current_screen, debug): """ Save and keep the output image in memory in order to keep the good colors on the screenshot. Parameters ---------- current_screen: PIL.Image.Image The taken picture on which the search will be made. debug: bool The activation of the debug mode. If << True >> takes a screenshot of the screen. Default is << False >>. Raises ------ RobotException Throw an error if the user launching the function cannot write on disk. Return ------ output_image: ndarray The image as a numpy array. """ try: current_screen.save("debug_screen.png") output_image = cv2.imread("debug_screen.png") if not debug: os.remove("debug_screen.png") return output_image except Exception: RobotException().cannot_write_on_disk_exception()
def __set_image_up(self, image): """ Set up the image in the template. It checks if the path to the image is correct. Parameters ---------- image: str The path to the image we are looking for. Raises ------ RobotException If the image has not been found. Return ------ template: ndarray The template of the image. w: int The width of the image. h: height The height of the image. """ try: template = cv2.imread(image, 0) w, h = template.shape[::-1] return template, w, h except Exception: RobotException().wrong_path_to_image_exception(image)
def restore_window(self): """ Restore the window focused. Raises ------ RobotException If not any window has been focused earlier. """ try: self.handle.restore() except AttributeError: RobotException().no_window_focused_exception()
def minimize_window(self): ''' Minimize the window focused. Raises ------ RobotException If not any window has been focused earlier. ''' try: self.handle.minimize() except AttributeError: RobotException().no_window_focused_exception()
def move_cursor_to_image(image, precision=0.8, timeout=10, timestamp=0.2, offset=0): """ Move the cursor in the middle of the given image depending on the offset. If the image is not found, when the timeout is elapsed, an error is thrown. Parameters ---------- image: str The path to the image we are looking for. precision: double, optional The percentage of recognition to use. Default is << 0.8 >>, meaning 80% similar. timeout: int, optional The duration elapsed before raising an error. Value is in second. Default is << 10 >> seconds. timestamp: double, optional The time the movement takes to move from the current position to the found position. offset: int, float, optional The distance maximum from the targeted point. Default is << 0 >>. Raises ------ RobotException If the image has not been found after the duration set in the timeout parameter is elapsed. The exception is raised by the function << wait_until_image_appear >>. If the offset is too high and may cause the cursor to be out of the image. """ img = cv2.imread(image) height, width, channels = img.shape maximum_offset = width / 2 if maximum_offset > height / 2: maximum_offset = height / 2 if offset > maximum_offset: RobotException().offset_too_high_exception(offset, maximum_offset) pos = Image().wait_until_image_appear(image, precision, timeout, timestamp) pyautogui.moveTo(pos[0] + width / 2 + random.uniform(0, offset), pos[1] + height / 2 + random.uniform(0, offset), timestamp)
def wait_until_image_appear(self, image, precision=0.8, timeout=10, timesample=0.1): ''' Wait until the given image appears in the screen for a given duration. If the image is not found, when the timeout is elapsed, an error is thrown. Parameters ---------- image: str The path to the image we are looking for. precision: double, optional The percentage of recognition to use. Default is << 0.8 >>, meaning 80% similar. timeout: int, optional The duration elapsed before raising an error. Value is in second. Default is << 10 >> seconds. timesample: double, optional The duration elapsed between two checks of the image. Value is in second. Default is << 0.1 >> second. Raises ------ RobotException If the image has not been found after the duration set in the timeout parameter is elapsed. Return ------ pos: tuple The location of the image. The top-left corner of the found image. ''' pos = self.search_image(image, precision) start_time = time.clock() while pos[0] == -1: time.sleep(timesample) pos = self.search_image(image, precision) if time.clock() - start_time > timeout: RobotException().image_not_found_after_duration_exception( image, timeout) return pos
def focus_window_with_exact_name(self, name): """ Set the found window in the foreground. Parameters ---------- name: str The exact name of the searched window. Raises ------ RobotException If not any window with the name given has been found. """ for title in gw.getAllTitles(): if name == title: self.handle = gw.getWindowsWithTitle(title)[0] self.handle.activate() break if self.handle is None: RobotException().no_window_matching_name_exception(name)
def focus_window_containing(self, name): """ Set the found window in the foreground. Parameters ---------- name: str The name or a part of the name of the searched window. Raises ------ RobotException If not any window containing the name or part of the name given has been found. """ for title in gw.getAllTitles(): if name in title: self.handle = gw.getWindowsWithTitle(title)[0] self.handle.activate() break if self.handle is None: RobotException().no_window_containing_text_exception(name)
def highlight_image(self, image, precision=0.8, color=(0, 0, 255), width=2, name=None, debug=False): """ Highlight the searched image in the current screen. If the image is found multiple times, it will draw a rectangle arround each. Take a screenshot as << debug_screen.png >> then read it with cv2 to keep the good colors. Parameters ---------- image: str The path to the image we are looking for. precision: double, optional The percentage of recognition to use. Default is << 0.8 >>, meaning 80% similar. color: bgr, optional The color in BGR-format meaning colors are given as following: blue, green and red. Default is << (0, 0, 255) >> which is red color. width: int, optional The width of the square borders. Value is in pixel. Default is << 2 >> pixel. name: str, optional The picture name if given. Otherwise the name will be such as << imagerobot-screenshot-XXX.png >>. Default is << None >>. debug: bool, optional The activation of debug mode. If << True >> takes a screenshot of the screen. Default is << False >>. Raises ------ RobotException Throw an error if the user launching the function cannot write on disk. Throw an error if the user already has 999 screenshots in the repository. Throw an error if the user set a name in a wrong format without finishing by << .png >> nor << .jpg >>. Output ------ A screenshot named << imagerobot-screenshot-XXX.png >> (or with the given name) is created with squares around the image searched. """ if self.region is None: current_screen = pyautogui.screenshot() else: current_screen = pyautogui.screenshot(region=self.region) output_image = self.__prepare_output_image(current_screen, debug) output_name = self.__check_output_name(name) img_rgb = np.array(current_screen) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template, w, h = self.__set_image_up(image) res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) loc = np.where(res >= precision) try: for pt in zip(*loc[::-1]): cv2.rectangle(output_image, pt, (pt[0] + w, pt[1] + h), color, width) except UnboundLocalError: RobotException().image_not_found_exception(image) cv2.imwrite(output_name, output_image)