提交 04e2a310 编写于 作者: Q qq_38870145

Tue Apr 1 18:47:00 CST 2025 inscode

上级 efc92edc
...@@ -11,14 +11,18 @@ import os ...@@ -11,14 +11,18 @@ import os
from PIL import Image from PIL import Image
from time import sleep from time import sleep
def genDir(): # cut
cut_img_paths=[]
# full
full_img_paths=[]
def gen_dir():
cur_timestemp = int(round(time.time() * 1000)) cur_timestemp = int(round(time.time() * 1000))
dir = './screen_shot/outlook/{ts}'.format(ts=cur_timestemp) dir = './screen_shot/outlook/{ts}'.format(ts=cur_timestemp)
os.makedirs(dir, exist_ok=True) os.makedirs(dir, exist_ok=True)
return dir return dir
def cutImg(screenshot_path,element,baseDir,loc): def cut_img(screenshot_path,element,baseDir,loc):
# 获取元素坐标和尺寸 # 获取元素坐标和尺寸
location = element.location # {x: number, y: number} location = element.location # {x: number, y: number}
size = element.size # {width: number, height: number} size = element.size # {width: number, height: number}
...@@ -32,87 +36,148 @@ def cutImg(screenshot_path,element,baseDir,loc): ...@@ -32,87 +36,148 @@ def cutImg(screenshot_path,element,baseDir,loc):
# 使用 Pillow 裁剪图像 # 使用 Pillow 裁剪图像
image = Image.open(screenshot_path) image = Image.open(screenshot_path)
cropped_image = image.crop((left, top, right, bottom)) cropped_image = image.crop((left, top, right, bottom))
cropped_image.save(f"{baseDir}/cut_{loc}.png") cut_file_name=f"{baseDir}/cut_{loc}.png"
cropped_image.save(cut_file_name)
class ScreenShot: global cut_img_paths
__JS__ = { cut_img_paths.append(cut_file_name)
'scroll_to_bottom': "window.scroll({top:document.body.clientHeight,left:0,behavior:'auto'});",
'scroll_to_y': "window.scroll({top:%d,left:0,behavior:'auto'});",
} def screen_shot(driver):
__base_end__ = 'tmp_end.png' dir=gen_dir()
__scroll_bottom__ = 'scroll_to_bottom' # global cut_img_paths
__scroll_y__ = 'scroll_to_y' # cut_img_paths=[]
__body__ = '//body' # global full_img_paths
__height__ = 'height' # full_img_paths=[]
__clear_shell__ = 'rm -rf *.png'
__RGB__ = 'RGB' # 当前滚动高度
scrollTop=driver.execute_script(
@classmethod 'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollTop;')
def screen_shot(cls, driver, title, uploader_url='', delete=False): # 可滚动高度范围
dir=genDir() scrollHeight=driver.execute_script(
# 当前滚动高度 'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollHeight;')
scrollTop=driver.execute_script( # 渲染的可视区域
'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollTop;') clientHeight=driver.execute_script(
# 可滚动高度范围 'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].clientHeight;')
scrollHeight=driver.execute_script(
'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollHeight;') print('scrollTop', scrollTop,type(scrollTop))
# 渲染的可视区域 print('scrollHeight',scrollHeight)
clientHeight=driver.execute_script( print('clientHeight', clientHeight)
'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].clientHeight;') lastScrollTop=scrollTop
# 次数索引
print('scrollTop', scrollTop,type(scrollTop)) i=0
print('scrollHeight',scrollHeight)
print('clientHeight', clientHeight) # 等待元素加载并可见
lastScrollTop=scrollTop element = WebDriverWait(driver, 10).until(
# 次数索引 EC.visibility_of_element_located((By.ID, "ConversationReadingPaneContainer"))
i=0 )
# 等待元素加载并可见 window_height = driver.execute_script('return window.innerHeight;')
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "ConversationReadingPaneContainer"))
) if lastScrollTop<scrollHeight:
img_path=f'{dir}/custom_{i}.png'
if lastScrollTop<scrollHeight: driver.save_screenshot(img_path)
img_path=f'{dir}/custom_{i}.png' cut_img(img_path,element,dir,i)
full_img_paths.append(img_path)
# 滚动底部 + 渲染高度 翻页滚动
while math.ceil(lastScrollTop+1) < scrollHeight:
i += 1
# 加渲染高度 翻页 好拼接
lastScrollTop += clientHeight
driver.execute_script(
'document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollTop={scrollTop}'.format(
scrollTop=lastScrollTop))
sleep(.5)
img_path = f'{dir}/custom_{i}.png'
driver.save_screenshot(img_path) driver.save_screenshot(img_path)
cutImg(img_path,element,dir,i) cut_img(img_path, element, dir, i)
# 滚动底部 + 渲染高度 翻页滚动 full_img_paths.append(img_path)
while lastScrollTop < scrollHeight: end_rect_bottom = driver.execute_script(
i += 1 'return document.querySelector(".T_6Xj").getBoundingClientRect().bottom;')
# 加渲染高度 翻页 好拼接 end_rect_top = driver.execute_script('return document.querySelector(".T_6Xj").getBoundingClientRect().top;')
lastScrollTop += clientHeight # end
driver.execute_script( if end_rect_top < window_height and end_rect_bottom > 0:
'document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollTop={scrollTop}'.format( break
scrollTop=lastScrollTop)) else:
sleep(.5) # 完整email
img_path = f'{dir}/custom_{i}.png' img_path=f'{dir}/full_screen_email.png'
driver.save_screenshot(img_path) driver.save_screenshot(img_path)
cutImg(img_path, element, dir, i)
else: cut_len=len(cut_img_paths)
# 完整email first=0
img_path=f'{dir}/full_screen_email.png' second=1
driver.save_screenshot(img_path)
print('cut_img_paths',cut_img_paths)
print('cut_len',cut_len)
@classmethod # while second<cut_len:
def __join_images__(cls, png1, png2, size=0, output='result.png'): # gen_img_path = f'{dir}/temp_result_{i}.png'
""" # if first ==0:
图片拼接 # img1_path=cut_img_paths[first]
:param png1: 图片1 # else:
:param png2: 图片2 # img1_path= gen_img_path
:param size: 两个图片重叠的距离 # join_images(img1_path,cut_img_paths[second],0,gen_img_path)
:param output: 输出的图片文件 # second += 1
:return: # print('second',second)
""" # 裁剪顶部高度 渲染高度
size = size * 2 crop_height=driver.execute_script('return document.getElementById("ConversationReadingPaneContainer").firstChild.offsetHeight;')
img1, img2 = Image.open(png1), Image.open(png2) # 8px padding
size1, size2 = img1.size, img2.size vertical_concatenate_with_crop(cut_img_paths, f'{dir}/result_email.png',crop_height+16)
joint = Image.new(cls.__RGB__, (size1[0], size1[1] + size2[1] - size))
loc1, loc2 = (0, 0), (0, size1[1] - size)
joint.paste(img1, loc1) def vertical_concatenate_with_crop(image_paths, output_path, crop_height=100):
joint.paste(img2, loc2) """
joint.save(output) 纵向拼接多图,并对第二张图裁剪指定高度
:param image_paths: 图片路径列表(按顺序从上到下)
:param output_path: 输出文件路径
:param crop_height: 第二张图裁剪的高度(默认 100px)
"""
images = []
# 读取并处理图片
for idx, path in enumerate(image_paths):
img = Image.open(path)
if idx >= 1: # 第二张图之后裁剪
width, height = img.size
# 确保裁剪高度不超出原图范围
actual_crop = min(crop_height, height)
print('actual_crop',actual_crop)
# 左上
img = img.crop((0, actual_crop, width, height))
images.append(img)
# 计算总高度和最大宽度
total_height = sum(img.height for img in images)
max_width = max(img.width for img in images)
# 创建空白画布并拼接
merged = Image.new('RGB', (max_width, total_height))
y_offset = 0
for img in images:
# 居中处理宽度不一致的图片
x_offset = (max_width - img.width) // 2
merged.paste(img, (x_offset, y_offset))
y_offset += img.height
merged.save(output_path)
def join_images(png1, png2, size=0, output=f'{dir}/temp_result.png'):
"""
图片拼接
:param png1: 图片1
:param png2: 图片2
:param size: 两个图片重叠的距离
:param output: 输出的图片文件
:return:
"""
size = size * 2
img1, img2 = Image.open(png1), Image.open(png2)
size1, size2 = img1.size, img2.size
joint = Image.new('RGB', (size1[0], size1[1] + size2[1] - size))
loc1, loc2 = (0, 0), (0, size1[1] - size)
joint.paste(img1, loc1)
joint.paste(img2, loc2)
joint.save(output)
sleep(.5)
def run(): def run():
global driver global driver
...@@ -177,8 +242,7 @@ def mapMSg(): ...@@ -177,8 +242,7 @@ def mapMSg():
# return base64; # return base64;
# }) # })
# """) # """)
cur_timestemp = int(round(time.time() * 1000)) screen_shot(driver)
ScreenShot.screen_shot(driver, 'outlook_' + str(cur_timestemp))
# print('base64Data',base64Data) # print('base64Data',base64Data)
# email_box=driver.find_element(By.ID,':mt') # email_box=driver.find_element(By.ID,':mt')
break break
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册