From c223b832e1381f86d661babb09f0532e0f095c31 Mon Sep 17 00:00:00 2001 From: Diego DG Date: Sun, 17 Jul 2022 21:25:14 -0500 Subject: [PATCH] Fix: Fixed issue when taking screenshots and images are displayed cropped --- Screenshot/Screenshot_Clipping.py | 61 +++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/Screenshot/Screenshot_Clipping.py b/Screenshot/Screenshot_Clipping.py index fb0422e..0211450 100644 --- a/Screenshot/Screenshot_Clipping.py +++ b/Screenshot/Screenshot_Clipping.py @@ -1,6 +1,5 @@ import os import time -import uuid from PIL import Image from selenium import webdriver @@ -31,8 +30,17 @@ def __init__(self): """ pass + @staticmethod + # Take temporary screenshot of the web page to get the size of the image + def __get_screen_size(driver: WebDriver) -> dict: + driver.get_screenshot_as_file('screenshot.png') + image = Image.open('screenshot.png') + width, height = image.size + + return {'width': width, 'height': height} + def full_Screenshot(self, driver: WebDriver, save_path: str = '', image_name: str = 'selenium_full_screenshot.png', - elements: list = None, is_load_at_runtime:bool = False,load_wait_time: int = 5) -> str: + elements: list = None, is_load_at_runtime: bool = False, load_wait_time: int = 5, multi_images: bool = False) -> str: """ Take full screenshot of web page Args: @@ -42,6 +50,7 @@ def full_Screenshot(self, driver: WebDriver, save_path: str = '', image_name: st elements: List of Xpath of elements to hide from web pages is_load_at_runtime: Page Load at runtime load_wait_time: The Wait time while loading full screen + multi_images: The flag is uses to capture multiple images and create single image in vertical format Returns: str : The path of image @@ -78,7 +87,6 @@ def full_Screenshot(self, driver: WebDriver, save_path: str = '', image_name: st time.sleep(2) rectangles = [] - i = 0 while i < total_height: ii = 0 @@ -92,23 +100,54 @@ def full_Screenshot(self, driver: WebDriver, save_path: str = '', image_name: st rectangles.append((ii, i, top_width, top_height)) ii = ii + viewport_width i = i + viewport_height - stitched_image = Image.new('RGB', (total_width, total_height)) + stitched_image = None previous = None part = 0 + # This value indicates if is the first part of the screenshot, or it is the rest of the screenshot + init_canvas = True + # Get the screenshot and save the dimensions of the image, this will be useful for create a + # correct canvas with correct dimensions + # and not show images with a wrong size or cut + size_screenshot = self.__get_screen_size(driver) + # Get temporary sum of height of the total pages + height_canvas = size_screenshot['height'] * len(rectangles) + + # Compare if the screenshot it's only one part and assign the correct dimensions of the screenshot size + # Or assign the height of the total screenshot + if multi_images: + # Assign the height of the total screenshot at canvas even if not used at the moment + stitched_image = Image.new('RGB', (size_screenshot['width'], height_canvas)) + else: + # Assign the dimensions corresponding to the size of the uniq screenshot + stitched_image = Image.new('RGB', (size_screenshot['width'], size_screenshot['height'])) + + # This constant is used top offset the image in the canvas + jump = round(size_screenshot['height'] / 2) + # With take multiple screenshots this value is used to adjust the position of the image in the canvas + # This value know update every time the screenshot is taken + top_offset = jump + for rectangle in rectangles: - if not previous is None: + if previous is not None: driver.execute_script("window.scrollTo({0}, {1})".format(rectangle[0], rectangle[1])) - time.sleep(3) + time.sleep(1) self.hide_elements(driver, elements) - + file_name = "part_{0}.png".format(part) driver.get_screenshot_as_file(file_name) screenshot = Image.open(file_name) + if rectangle[1] + viewport_height > total_height: - offset = (rectangle[0], total_height - viewport_height) + offset = (rectangle[0], rectangle[1] + top_offset) else: - offset = (rectangle[0], rectangle[1]) + if init_canvas: + offset = (rectangle[0], rectangle[1]) + init_canvas = False + else: + offset = (rectangle[0], rectangle[1] + top_offset) + top_offset = jump + top_offset + stitched_image.paste(screenshot, offset) del screenshot os.remove(file_name) @@ -118,7 +157,7 @@ def full_Screenshot(self, driver: WebDriver, save_path: str = '', image_name: st stitched_image.save(save_path) return save_path - def get_element(self, driver: WebDriver, element: WebElement, save_location: str, image_name : str = 'cropped_screenshot.png', to_hide: list = None) -> str: + def get_element(self, driver: WebDriver, element: WebElement, save_location: str, image_name: str = 'cropped_screenshot.png', to_hide: list = None) -> str: """ Usage: Capture Element screenshot as a image @@ -131,7 +170,7 @@ def get_element(self, driver: WebDriver, element: WebElement, save_location: str Raises: N/A """ - image = self.full_Screenshot(driver, save_path=save_location, image_name='clipping_shot.png', elements=to_hide) + image = self.full_Screenshot(driver, save_path=save_location, image_name='clipping_shot.png', elements=to_hide, multi_images=True) location = element.location size = element.size x = location['x']