def get_single_rgb_color_from_zone(self, zone):
        screen = self.get_area(zone)
        scr = ImageProcessor()._get_screenshot(screen)
        rgb = scr.convert('RGB')
        r, g, b = rgb.getpixel((1, 1))

        return [r, g, b]
 def _init_static_elements(self, screen=None):
     """Init position of static elements of window. Assumes that window is on screen or error will be raised
     """
     #init buttons
     for button in self.buttons.values():
         button.find_on_screen(screen)
     screen = ImageProcessor().get_screenshot() if screen is None else screen
     #check window
     if "check" in self.config:
         images_to_check = []
         if isinstance(self.config["check"], list):
             for img_name in self.config["check"]:
                 images_to_check.append(get_image_from_config(img_name))
             if type(images_to_check[0]) == list:
                 for image in images_to_check[0]:
                     res = ImageProcessor().is_image_on_screen(image, screen=screen)
                     if not res:
                         msg = "Image {} was not found at screen".format(image)
                         ErrorHandler().report_error(msg)
                         raise RuntimeError(msg)
             elif type(images_to_check) == list:
                 for image in images_to_check:
                     try:
                         ImageProcessor().image_should_be_on_screen(image[0], image[1], screen=screen)
                     except RuntimeError as e:
                         pass
         else:
             images_to_check.append(get_image_from_config(self.config["check"]))
             for image in images_to_check:
                 ImageProcessor().image_should_be_on_screen(image[0], image[1], screen=screen)
def get_button_info(config):
    """Returns list of states info"""
    states = {}
    # config can contain simple filename
    if isinstance(config, (str, bytes)):
        states[STATE_NORMAL] = (ImageProcessor().load_image(config),
                                DEFAULT_THRESHOLD)

    elif isinstance(config, dict):
        # or filename and threshold
        # or list of states
        # or threshold and list of states
        default_threshold = config[
            THRESHOLD_LABEL] if THRESHOLD_LABEL in config else DEFAULT_THRESHOLD
        if IMAGE_LABEL in config:
            states[STATE_NORMAL] = (ImageProcessor().load_image(
                config[IMAGE_LABEL]), default_threshold)
        elif STATES_LABEL in config:
            states_config = config[STATES_LABEL]
            for state_label in POSSIBLE_STATES:
                if state_label in states_config:
                    states[state_label] = get_state_info(
                        states_config[state_label], default_threshold)
        else:
            raise AssertionError("image or states must be defined")
    else:
        raise AssertionError("Lists are not supported in button block")

    return states
def find_on_screen(states, screen=None):
    #creates the Class object - image_processor
    image_processor = ImageProcessor()
    #checks if screen is provided, else gets the active window screenshot
    screen = screen if screen is not None else image_processor._get_screenshot(
    )
    #collects images
    images_to_find = states.values()
    #searches for image in state on screen
    coords = image_processor.find_one_of(images_to_find, screen=screen)
    #if found - calculates the image position (coordinates)
    if coords is not None:
        return coords.get_pos()
    #try again if not found in first attempt
    ErrorHandler().report_warning("First try was unsuccessful")
    utils.sleep(0.020)
    coords = image_processor.find_one_of(images_to_find)
    if coords is not None:
        return coords.get_pos()

    #no one state is found
    #prepare the error message content
    images = []
    for state_name, state_info in states.items():
        images.append((state_name, state_info[0]))
    msg = "Button not found on screen in all possible states"
    images.append(("screen", screen))
    ErrorHandler().report_error(msg, *images)
    raise RuntimeError(msg)
    def wait_for_animation_starts(self,
                                  zone=None,
                                  timeout=15,
                                  threshold=0.99,
                                  step=0.5):
        #convert passed args to float values
        timeout = float(timeout)
        threshold = float(threshold)
        step = float(step)
        # gets the first screenshot from given zone (if zone is none, takes the whole active window)
        new_screen = ImageProcessor()._get_screen(False, zone)
        # saves the time starting point (when the first screenshot was taken)
        start_time = datetime.datetime.now()

        #In a loop compares the screenshot with previously taken from screen.
        #If images are NOT identical returns True, else continue until timeout occurs - throws error and returns False.
        while True:
            utils.sleep(step)
            old_screen = new_screen
            new_screen = ImageProcessor()._get_screen(False, zone)

            result = ImageProcessor().find_image_result(
                new_screen, old_screen, threshold)
            if not result.found:
                return True
            if (datetime.datetime.now() - start_time).seconds > timeout:
                break

        ErrorHandler().report_warning(
            "Timeout exceeded while waiting for animation starts")
        return False
    def is_complex_template_on_screen(self,
                                      templates_set,
                                      threshold=0.99,
                                      cache=False,
                                      zone=None):
        """Checks if the elements of the given templates set are on screen. Returns *bool*: True if all the parts from the
        set are found.
            
            Templates should be passed as a list.
        
        Examples:
        | ${complex_template} =  Is Complex Template On Screen | templates | threshold=0.99 | zone=None
        
        """

        on_screen = True
        screen = ImageProcessor(self.error_handler,
                                self.output_dir).get_screenshot()
        for image in templates_set:
            on_screen &= ImageProcessor(self.error_handler,
                                        self.output_dir)._is_image_on_screen(
                                            image, threshold, cache, zone,
                                            screen)
            if not on_screen:
                break

        return on_screen
Esempio n. 7
0
    def get_number_with_text_from_zone(self,
                                       zone=None,
                                       lang=None,
                                       resize_percent=0,
                                       resize=0,
                                       contrast=0,
                                       background=None,
                                       invert=False,
                                       brightness=0,
                                       change_mode=True,
                                       tessdata_dir=None,
                                       cache=False):
        """Returns only number from zone with text and number. For arguments details check `Get Number From Zone`
            Examples:
            | Get Number With Text From Zone | zone=[x  y  w  h] | lang=eng | resize_percent=15 | resize=0.95 | contrast=0.1 | background=${None} | invert=${False} |
            brightness=0 | change_mode=${True}
        """

        self.window_area = GUIProcess().get_window_area()

        if background is not None:
            img = ImageProcessor(
                self.error_handler,
                self.screenshot_folder).get_image_to_recognize_with_background(
                    zone, resize_percent, contrast, background, invert,
                    brightness, cache)
        else:
            img = ImageProcessor(
                self.error_handler,
                self.screenshot_folder).get_image_to_recognize(
                    zone, resize_percent, contrast, invert, brightness,
                    change_mode, self.window_area, cache)

        if int(resize) > 0:
            resize = int(resize)
            img = resize_img(img, resize)

        config = ""
        if lang:
            mydir = os.path.abspath(os.path.dirname(__file__))
            resdir = os.path.abspath(os.path.join(os.sep, mydir, tessdata_dir))
            config += ("--tessdata-dir %s -l %s " % (resdir, lang)).replace(
                "\\", "//")
        config += "-psm 6"

        txt = image_to_string(img, config=config)

        num = re.compile('[0-9|.0-9]+')
        num = num.findall(txt)
        num = ''.join(num)

        try:
            return float(num)
        except ValueError as e:
            msg = "Error while parsing text:" + str(e)
            ErrorHandler(self.screenshot_folder).report_error(
                msg, ("img", img))
            raise
Esempio n. 8
0
    def get_float_number_from_zone(self,
                                   zone=None,
                                   lang=None,
                                   resize_percent=0,
                                   resize=0,
                                   contrast=0,
                                   background=None,
                                   invert=False,
                                   brightness=0,
                                   change_mode=True,
                                   tessdata_dir=None,
                                   cache=False):
        """Returns the *float*. For details check `Get Number From Zone`
            Examples:
            | Get Float Number From Zone | zone=[x  y  w  h] | lang=eng | resize_percent=15 | resize=0.95 | contrast=0.1 | background=${None} | invert=${False} |
            brightness=0 | change_mode=${True}
        """

        self.window_area = GUIProcess().get_window_area()

        if background is not None:
            img = ImageProcessor(
                self.error_handler,
                self.screenshot_folder).get_image_to_recognize_with_background(
                    zone, resize_percent, contrast, background, brightness,
                    invert, cache)
        else:
            img = ImageProcessor(
                self.error_handler,
                self.screenshot_folder).get_image_to_recognize(
                    zone, resize_percent, contrast, invert, brightness,
                    change_mode, self.window_area, cache)

        if int(resize) > 0:
            resize = int(resize)
            img = resize_img(img, resize)

        config = ""
        if lang:
            mydir = os.path.abspath(os.path.dirname(__file__))
            resdir = os.path.abspath(os.path.join(os.sep, mydir, tessdata_dir))
            config += ("--tessdata-dir %s -l %s " % (resdir, lang)).replace(
                "\\", "//")
        config += "-psm 8 -c tessedit_char_whitelist=.,0123456789"

        txt = image_to_string(img, config=config)
        txt = float(txt)
        try:
            return txt
        except ValueError as e:
            msg = "Error while parsing number: " + str(e)
            ErrorHandler(self.screenshot_folder).report_error(
                msg, ("img", img))
            raise
    def is_any_part_of_complex_template_on_screen(self,
                                                  threshold=None,
                                                  cache=False,
                                                  zone=None):
        screen = ImageProcessor().get_screenshot() if not cache else None
        for image in self.images:
            if ImageProcessor().is_image_on_screen(
                    image[0], _get_threshold(image, threshold), cache, zone,
                    screen):
                return True

        return False
Esempio n. 10
0
    def __init__(self, screenshot_folder=None):
        self.screenshot_folder = screenshot_folder

        self.error_handler = ErrorHandler(self.screenshot_folder)

        Template.__init__(self, self.error_handler, self.screenshot_folder)
        ComplexTemplate.__init__(self, self.error_handler,
                                 self.screenshot_folder)
        GUIProcess.__init__(self)
        Zone.__init__(self, self.screenshot_folder, self.error_handler)
        ImageProcessor.__init__(self, self.error_handler,
                                self.screenshot_folder)
        Animations.__init__(self, self.error_handler, self.screenshot_folder)
    def is_animating(self, zone=None, threshold=0.99, step=0.5):
        # convert passed args to float values
        threshold = float(threshold)
        step = float(step)

        #gets the first screenshot than waits for 'step' time and gets the second screenshot
        old_screen = ImageProcessor()._get_screen(False, zone)
        utils.sleep(step)
        new_screen = ImageProcessor()._get_screen(False, zone)

        #compares the first and the second screenshots, returns result. If screenshots are identical - True.
        return not ImageProcessor().find_image_result(new_screen, old_screen,
                                                      threshold).found
def get_state_info(config, default_threshold):
    # config can contain simple filename
    # or filename and threshold (threshold there is prior to default)

    #checks the passed config entry (line from yaml) and loads image
    if isinstance(config, (str, bytes)):
        return (ImageProcessor().load_image(config), default_threshold)
    elif isinstance(config, dict):
        filename = config[IMAGE_LABEL]
        threshold = config[
            THRESHOLD_LABEL] if THRESHOLD_LABEL in config else default_threshold
        return (ImageProcessor().load_image(filename), threshold)
    else:
        raise AssertionError("Lists are not supported in state block")
    def is_complex_template_on_screen(self,
                                      threshold=None,
                                      cache=False,
                                      zone=None):
        on_screen = True
        screen = ImageProcessor().get_screenshot() if not cache else None

        for image in self.images:
            on_screen &= ImageProcessor().is_image_on_screen(
                image[0], _get_threshold(image, threshold), cache, zone,
                screen)
            if not on_screen:
                break

        return on_screen
    def get_number_from_zone(self,
                             lang=None,
                             resize_before=0,
                             resize_after=0,
                             contrast=0,
                             cache=False,
                             contour=False,
                             invert=False,
                             brightness=0,
                             change_mode=True):
        img = ImageProcessor().get_image_to_recognize(self.get_area(), cache,
                                                      resize_before, contrast,
                                                      contour, invert,
                                                      brightness, change_mode)

        resize = int(resize_after)
        if int(resize) > 0:
            resize = int(resize)
            img = resize_after_screenshot_modification(img, resize)

        config = ""
        config += "-psm 8 -c tessedit_char_whitelist=0123456789"

        try:
            return int(image_to_string(img, config=config))
        except ValueError as e:
            msg = "Error while parsing number: " + str(e)
            ErrorHandler().report_error(msg, ("img", img))
            raise
    def find_on_screen(self, screen=None):
        found = ImageProcessor().find_multiple_images(self.image_info[0],
                                                      self.image_info[1],
                                                      screen=screen)
        if self.expected is not None:
            if self.expected != len(found):
                images = [("button", self.image_info[0])]
                if len(found) > 0:
                    images.append(("screen", found[0].screen))
                elif screen is not None:
                    images.append(("screen", screen))

                msg = "Found {} buttons, but only {} expected".format(
                    len(found), self.expected)
                ErrorHandler().report_error(msg, *images)
                raise RuntimeError(msg)

        ErrorHandler().report_info("Found {} buttons {} on screen".format(
            len(found), self.name))
        #sort in horizontal or vertical direction
        sorted_found = sorted(found,
                              key=lambda res: res.x
                              if self.direction == 0 else res.y)
        #save pos for every button
        self.buttons = [entry.get_pos() for entry in sorted_found]
    def get_number_with_text_from_zone(self,
                                       lang=None,
                                       resize_before=0,
                                       resize_after=0,
                                       contrast=0,
                                       cache=False,
                                       contour=False,
                                       invert=False,
                                       brightness=0,
                                       change_mode=True):
        img = ImageProcessor().get_image_to_recognize(self.get_area(), cache,
                                                      resize_before, contrast,
                                                      contour, invert,
                                                      brightness, change_mode)
        resize = int(resize_after)
        if resize > 0:
            img = resize_after_screenshot_modification(img, resize)

        config = ""
        config += "-psm 6"

        txt = image_to_string(img, config=config)

        num = re.compile('[0-9]')
        num = num.findall(txt)
        num = ''.join(num)
        num = int(num)

        try:
            return num
        except ValueError as e:
            msg = "Error while parsing text:" + str(e)
            ErrorHandler().report_error(msg, ("img", img))
            raise
def resize_after_screenshot_modification(img, resize):
    """"Stretches the initial image
                PIL.IMAGE filters:
                ANTIALIAS
                NEAREST
                BICUBIC
                BIL
                INEAR
    """
    """
    Loads an image from ``filename``, resizes it by ``resize_percent`` and returns the resized image.
    The resized image will is saved by default ``resized.png``.
    Percentage is relative to original size, for example 5 is half, 10 equal and 20 double size.
    Percentage must be greater than zero.
    """

    if resize > 0:
        origFile = ImageProcessor()._make_up_filename()
        img.save(origFile)
        origresize = Image.open(origFile)
        old_width, old_height = origresize.size
        new_width = int(old_width * resize)
        new_height = int(old_height * resize)
        img = img.resize((new_width, new_height), Image.ANTIALIAS)
        img.save('resized.png')
    return img
    def is_button_active(self, index):
        if STATE_NORMAL in self.states:
            state_info = self.states[STATE_NORMAL]
            result = ImageProcessor().is_image_on_screen(
                state_info[0], state_info[1])
            if result:
                return True

        if STATE_HIGHLIGHTED in self.states:
            state_info = self.states[STATE_HIGHLIGHTED]
            result = ImageProcessor().is_image_on_screen(
                state_info[0], state_info[1])
            if result:
                return True

        return False
Esempio n. 19
0
    def wait_for_dynamic_button(self, index, timeout, threshold):
        """Any state"""
        images_to_find = []
        for state in sorted(self.states.values()):
            images_to_find.append((state[0], state[1], True))

        return ImageProcessor().wait_for_one_of(images_to_find, timeout)
 def wait_for_template_to_hide(self,
                               index=-1,
                               threshold=None,
                               timeout=15,
                               zone=None):
     image = self._get_template_image(index)
     return ImageProcessor().wait_for_image_to_hide(
         image[0], _get_threshold(image, threshold), timeout, zone)
 def wait_for_complex_template(self, threshold=None, timeout=15, zone=None):
     waiting_result = False
     for image in self.images:
         waiting_result = ImageProcessor().wait_for_image(
             image[0], _get_threshold(image, threshold), timeout, zone)
         if not waiting_result:
             return waiting_result
     return waiting_result
 def get_templates_count(self,
                         index=-1,
                         threshold=None,
                         cache=False,
                         zone=None):
     image = self._get_template_image(index)
     return ImageProcessor().get_images_count(
         image[0], _get_threshold(image, threshold), cache, zone)
 def template_should_not_be_on_screen(self,
                                      index=-1,
                                      threshold=None,
                                      cache=False,
                                      zone=None):
     image = self._get_template_image(index)
     return ImageProcessor().image_should_not_be_on_screen(
         image[0], _get_threshold(image, threshold), cache, zone)
Esempio n. 24
0
    def save_zone_content_to_output(self, zone):
        '''FOR DEBUG: saves the content (screenshot) of the provided zone. Pass zone. Image is saved in the output folder in launcher
        '''

        screen_img = ImageProcessor(self.error_handler,
                                    self.screenshot_folder)._screenshot(zone)
        ErrorHandler(self.screenshot_folder).save_pictures([(screen_img,
                                                             "zone")])
    def wait_for_activate_and_press(self, index, timeout, step=0.5):
        states_to_wait = []
        for state in STATES_ACTIVE:
            if state in self.states:
                states_to_wait.append(
                    (self.states[state][0], self.states[state][1], True))

        assert bool(
            states_to_wait
        ), "Button has not active states in list of possible states"

        result = ImageProcessor().wait_for_one_of(states_to_wait, timeout)
        if not result.found:
            raise RuntimeError(
                "Button was not found on screen or is in unknown state")

        self.click_center(result.get_pos(), 1)
    def get_image_from_zone(self, zone, image_name):
        """Returns image from given zone and saves it to 'output' under the provided image_name or default"""
        screen = self.get_area(zone)
        scr = ImageProcessor()._get_screenshot(screen)
        if image_name is not None:
            screen_name = image_name
        else:
            screen_name = 'image_from_zone'

        try:
            output = BuiltIn().get_variable_value('${OUTPUT_DIR}')
        except RobotNotRunningError:
            LOGGER.info('Could not get output dir, using default - output')
            output = os.path.join(os.getcwd(), 'output')

        scr.save(output + '\\' + screen_name + '.png')

        return output + '\\' + screen_name + '.png'
    def get_templates_count(self,
                            image,
                            threshold=0.99,
                            cache=False,
                            zone=None):
        """Counts the number of the given template occurences on screen (in the given zone).
            Returns an _integer_.
        
        Examples:
        | ${my_template} =  Get Templates Count | template | threshold=0.99 | zone=None
        
        """

        screen = ImageProcessor(self.error_handler,
                                self.output_dir)._get_screen(cache, zone)
        return ImageProcessor(self.error_handler,
                              self.output_dir)._get_images_count(
                                  image, threshold, cache, zone, screen)
 def find_image(self, image, threshold=0.99, cache=False, zone=None):
     #gets zone value
     zone = self.zones[zone].get_area() if zone is not None else None
     #searches for image on screen
     result = ImageProcessor().find_image(image, threshold, cache, zone)
     if result.found:
         return True
     else:
         return False
Esempio n. 29
0
    def get_float_number_from_zone(self,
                                   cache=False,
                                   zone=None,
                                   lang=None,
                                   resize_percent=0,
                                   resize=0,
                                   contrast=0,
                                   invert=False,
                                   brightness=0,
                                   change_mode=True,
                                   tessdata_dir=None):
        """Returns the *float*. For details check `Get Number From Zone`
            Examples:
            | Get Float Number From Zone | zone=[x  y  w  h] | lang=eng | resize_percent=15 | resize=0.95 | contrast=0.1 | background=${None} | invert=${False} |
            brightness=0 | change_mode=${True}
        """

        self.window_area = GUIProcess().get_window_area()

        img = ImageProcessor(self.error_handler,
                             self.screenshot_folder).get_image_to_recognize(
                                 zone, cache, resize_percent, contrast, invert,
                                 brightness, change_mode, self.window_area)

        if int(resize) > 0:
            resize = int(resize)
            origFile = ImageProcessor(
                self.error_handler,
                self.screenshot_folder)._make_up_filename()
            img.save(origFile)
            origresize = Image.open(origFile)
            width, height = origresize.size
            width_resize = width * int(resize) / width + width
            height_resize = height * int(resize) / height + height
            img = origresize.resize(
                (int(round(width_resize)), int(round(height_resize))),
                Image.ANTIALIAS)

        img.save(
            os.path.join(self.screenshot_folder,
                         'ImageLibrary_Zone_Image.png'))

        config = ""
        if lang:
            mydir = os.path.abspath(os.path.dirname(__file__))
            resdir = os.path.abspath(os.path.join(os.sep, mydir, tessdata_dir))
            config += ("--tessdata-dir %s -l %s " % (resdir, lang)).replace(
                "\\", "//")
        config += "-psm 8 -c tessedit_char_whitelist=.,0123456789"

        txt = image_to_string(img, config=config)
        txt = float(txt)
        try:
            return txt
        except ValueError as e:
            msg = "Error while parsing number: " + str(e)
            ErrorHandler(self.screenshot_folder).report_error(
                msg, ("img", img))
            raise
    def get_button_state(self, index):
        screen = ImageProcessor()._get_screenshot()
        images_to_find = self.states.values()
        coords = ImageProcessor().find_one_of(images_to_find, screen=screen)
        if coords is not None:
            for state_name, state_info in self.states:
                if state_info[0] is coords.image:
                    return state_name

        #no one state is found
        images = []

        for state_name, state_info in sorted(self.states.items()):
            images.append((state_name, state_info[0]))
        images.append(("screen", screen))
        msg = "Button {} not found on screen in all possible states".format(
            self.name)
        ErrorHandler().report_error(msg, *images)
        raise RuntimeError(msg)