def test_tuple_to_region(): region = geometry.to_region((11, 233, 56, 320)) assert isinstance(region, geometry.Region) assert region.left == 11 assert region.top == 233 assert region.right == 56 assert region.bottom == 320
def take_screenshot(self, filename=None, region=None) -> Image: """*DEPRECATED* Use keyword `RPA.Desktop.Take Screenshot` instead Take a screenshot of the current desktop. :param filename: Save screenshot to filename :param region: Region to crop screenshot to """ region = to_region(region) with mss.mss() as sct: if region is not None: image = sct.grab(region.as_tuple()) else: # mss uses the first monitor on the array as an # alias for a combined virtual monitor image = sct.grab(sct.monitors[0]) if filename is not None: filename = Path(filename).with_suffix(".png") mss.tools.to_png(image.rgb, image.size, output=filename) notebook_image(filename) self.logger.info("Saved screenshot as '%s'", filename) # Convert raw mss screenshot to Pillow Image. Might be a bit slow pillow_image = Image.frombytes("RGB", image.size, image.bgra, "raw", "BGRX") return pillow_image
def test_str_to_region(): region = geometry.to_region("10,20,30,40") assert isinstance(region, geometry.Region) assert region.left == 10 assert region.top == 20 assert region.right == 30 assert region.bottom == 40
def find( image: Union[Image.Image, Path], template: Union[Image.Image, Path], region: Optional[Region] = None, limit: Optional[int] = None, confidence: float = DEFAULT_CONFIDENCE, ) -> List[Region]: """Attempt to find the template from the given image. :param image: Path to image or Image instance, used to search from :param template: Path to image or Image instance, used to search with :param limit: Limit returned results to maximum of `limit`. :param region: Area to search from. Can speed up search significantly. :param confidence: Confidence for matching, value between 1 and 100 :return: List of matching regions :raises ImageNotFoundError: No match was found """ # Ensure images are in Pillow format image = _to_image(image) template = _to_image(template) # Convert confidence value to tolerance tolerance = _to_tolerance(confidence) # Crop image if requested if region is not None: region = geometry.to_region(region) image = image.crop(region.as_tuple()) # Verify template still fits in image if template.size[0] > image.size[0] or template.size[1] > image.size[1]: raise ValueError("Template is larger than search region") # Do the actual search start = time.time() matches: List[Region] = [] for match in _match_template(image, template, tolerance): matches.append(match) if limit is not None and len(matches) >= int(limit): break elif len(matches) >= LIMIT_FAILSAFE: logger.warning("Reached maximum of %d matches", LIMIT_FAILSAFE) break logging.info("Scanned image in %.2f seconds", time.time() - start) if not matches: raise ImageNotFoundError("No matches for given template") # Convert region coördinates back to full-size coördinates if region is not None: for match in matches: match.move(region.left, region.top) return matches
def show_region_in_image(self, image, region, color="red", width=5): """Draw a rectangle onto the image around the given region. :param image: image to draw onto :param region: coordinates for region or Region object :param color: color of rectangle :param width: line width of rectangle """ image = to_image(image) region = to_region(region) draw = ImageDraw.Draw(image) draw.rectangle(region.as_tuple(), outline=color, width=int(width)) return image
def find_template_in_image(self, image, template, region=None, limit=None, tolerance=None) -> List[Region]: """*DEPRECATED* Use keyword `Find` from library `RPA.Recognition` instead Attempt to find the template from the given image. :param image: Path to image or Image instance, used to search from :param template: Path to image or Image instance, used to search with :param limit: Limit returned results to maximum of `limit`. :param region: Area to search from. Can speed up search significantly. :param tolerance: Tolerance for matching, value between 0.1 and 1.0 :return: List of matching regions :raises ImageNotFoundError: No match was found """ # Ensure images are in Pillow format image = to_image(image) template = to_image(template) # Crop image if requested if region is not None: region = to_region(region) image = image.crop(region.as_tuple()) # Verify template still fits in image if template.size[0] > image.size[0] or template.size[1] > image.size[1]: raise ValueError("Template is larger than search region") # Strip alpha channels if image.mode == "RGBA": image = image.convert("RGB") if template.mode == "RGBA": template = template.convert("RGB") # Do the actual search start = time.time() matches = self.matcher.match(image, template, limit, tolerance) logging.info("Scanned image in %.2f seconds", time.time() - start) if not matches: raise ImageNotFoundError("No matches for given template") # Convert region coördinates back to full-size coördinates if region is not None: for match in matches: match.move(region.left, region.top) return matches
def crop_image(self, image, region, filename=None) -> None: """Crop an existing image. :param image: Image to crop :param region: Region to crop image to :param filename: Save cropped image to filename """ region = to_region(region) image = to_image(image) image = image.crop(region.as_tuple()) image.load() if filename: # Suffix isn't created automatically here image.save(Path(filename).with_suffix(".png"), "PNG") notebook_image(filename)
def find( image: Union[Image.Image, Path], text: str, confidence: float = DEFAULT_CONFIDENCE, region: Optional[Region] = None, ): """Scan image for text and return a list of regions that contain it (or something close to it). :param image: Path to image or Image object :param text: Text to find in image :param confidence: Minimum confidence for text similaritys """ image = to_image(image) confidence = clamp(1, float(confidence), 100) text = str(text).strip() if not text: raise ValueError("Empty search string") if region is not None: region = geometry.to_region(region) image = image.crop(region.as_tuple()) try: data = pytesseract.image_to_data(image, output_type=pytesseract.Output.DICT) except TesseractNotFoundError as err: raise EnvironmentError(INSTALL_PROMPT) from err lines = _dict_lines(data) matches = _match_lines(lines, text, confidence) if region is not None: for match in matches: match["region"] = match["region"].move(region.left, region.top) return matches
def test_region_to_region(): before = geometry.Region(10, 10, 20, 20) after = geometry.to_region(before) assert before == after