We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
可在多屏下不同排列方式所计算出的最大屏幕大小范围。比如1|2排列或者2|1排列,以及1/2 1\2,没有对齐在一条线上的情况。 另外也修复了多屏时,坐标空间默认按顺序横向排列的问题。现在可以绘制任意方式排列的多屏了(但其实我只有两块屏幕没有测试过上限) 已解决但还不会提交……先po在这里了…
测试环境Win7,19201080分辨率屏幕2,python 3.6
utils\get_screen_size.py
此模块仅用于获取屏幕设备大小 在App中 size=(self.winfo_screenwidth(), self.winfo_screenheight()) 这样的方法获取到的屏幕尺寸大小有问题。win11,机械革命电脑,分辨率超过1080p,屏幕缩放倍数150% """ from PIL import ImageGrab from functools import lru_cache from service.types import Size from screeninfo import get_monitors @lru_cache(1) def get_main_screen_size() -> Size: """ 获取主屏幕的大小 """ # return ImageGrab.grab().size return get_mutil_screen_size() # 以后如果涉及多屏幕显示器 # 获取其中任意一个等方法 # 还可以继续在这里添加函数 def get_mutil_screen_size() -> Size: total_width = 0 total_height = 0 monitors = get_monitors() # for index, monitor in enumerate(monitors): # screen_width = monitor.width # screen_height = monitor.height # total_width += screen_width # max_height = max(max_height, screen_height) (min_x, min_y, max_x, max_y) = calculate_bounding_box(monitors) total_width = max_x - min_x total_height = max_y - min_y return total_width, total_height from screeninfo.common import Monitor import typing # 计算多块屏幕拼接后的上下左右边界坐标,可以根据每块屏幕的坐标和大小进行计算。 # written by GPT-4o def calculate_bounding_box(monitors: typing.List[Monitor]): # 初始化边界坐标 min_x = float('inf') min_y = float('inf') max_x = float('-inf') max_y = float('-inf') for index, monitor in enumerate(monitors): current_min_x = monitor.x current_min_y = monitor.y current_max_x = monitor.x + monitor.width current_max_y = monitor.y + monitor.height # 更新全局边界 min_x = min(min_x, current_min_x) min_y = min(min_y, current_min_y) max_x = max(max_x, current_max_x) max_y = max(max_y, current_max_y) return (min_x, min_y, max_x, max_y)
除此之外还对绘图进行了坐标修正,在image_cache.py中增加了两个局部变量
center_x = 0 center_y = 0
对以下函数做了更新: service\image_cache.py
def _refresh(self): """ 将内部的绘制图片重置为一个纯黑色图片 :return: """ # self._cache = Image.new( # "RGBA", # self._size, # (0, 0, 0, 255), # ) screen_images = [] screen_info = [] total_width = 0 total_height = 0 # max_height = 0 monitors = get_monitors() # if len(monitors) != 2: # raise ValueError("当前代码仅针对两个屏幕的情况进行颜色区分,实际检测到的屏幕数量不是2个。") (min_x, min_y, max_x, max_y) = calculate_bounding_box(monitors) total_width = max_x - min_x total_height = max_y - min_y for index, monitor in enumerate(monitors): screen_width = monitor.width screen_height = monitor.height # total_width += screen_width # max_height = max(max_height, screen_height) # 创建一个与屏幕分辨率相同的空白图像,模式为RGB,背景填充为黑色 image = Image.new('RGBA', (screen_width, screen_height), (0, 0, 0)) # 创建一个ImageDraw对象,用于在图像上绘制边框 draw = ImageDraw.Draw(image) # 白色边框的宽度(可根据需要调整) border_width = 1 # 绘制白色边框,坐标计算是根据边框宽度和图像尺寸来确定四个边的位置 draw.rectangle([(0, 0), (screen_width - 2, screen_height - 2)], outline=(64, 64, 64), width=border_width) screen_images.append(image) if monitor.is_primary: # 记录主屏幕坐标 global center_x, center_y center_x = monitor.x - min_x center_y = monitor.y - min_y print(f"monitor{index} size ({monitor.width}, {monitor.height}), Location ({monitor.x}, {monitor.y}), is primary:({monitor.is_primary})") # 创建一个新的空白图像,用于组合所有屏幕图像,大小为总宽度和最大高度,背景也填充为黑色 combined_image = Image.new('RGBA', (total_width, total_height), (0, 0, 0)) x_offset = 0 y_offset = 0 # for screen_image in screen_images: for i in range(0, len(screen_images)): screen_image = screen_images[i] # combined_image.paste(screen_image, (x_offset, 0)) # x_offset += screen_image.width x_offset = monitors[i].x - min_x y_offset = monitors[i].y - min_y combined_image.paste(screen_image, (x_offset, y_offset)) self._cache = combined_image #print(f"screen full size ({total_width}, {total_height}), center({center_x}, {center_y}), ") def line(self, start: Position, end: Position, color=Colors.Move, width=2): """ Draw a line Parameters: - start: tuple of the line's start - end: tuple of the line's end """ offset = [center_x, center_y] start = tuple(a + b for a, b in zip(start, offset)) end = tuple(a + b for a, b in zip(end, offset)) start = start self._draw_transp_line(xy=[start, end], fill=color, width=width) def ellipse(self, x, y, color: Color, radius=10): """ Draw a point at `(x, y)` :param x: :param y: :param color: 注意:有四个值,最后一个值的不透明度最大值是255,不是float的0~1 :param radius: :return: None """ x = x + center_x y = y + center_y self._draw_transparent_ellipse( [(x - radius, y - radius), (x + radius, y + radius)], fill=color, )
已知问题:在程序运行时更改屏幕分辨率,进行绘图时会因为原有屏幕缓存大小与现有不符而崩溃。可重启程序解决。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
可在多屏下不同排列方式所计算出的最大屏幕大小范围。比如1|2排列或者2|1排列,以及1/2 1\2,没有对齐在一条线上的情况。
另外也修复了多屏时,坐标空间默认按顺序横向排列的问题。现在可以绘制任意方式排列的多屏了(但其实我只有两块屏幕没有测试过上限)
已解决但还不会提交……先po在这里了…
测试环境Win7,19201080分辨率屏幕2,python 3.6
utils\get_screen_size.py
除此之外还对绘图进行了坐标修正,在image_cache.py中增加了两个局部变量
对以下函数做了更新:
service\image_cache.py
已知问题:在程序运行时更改屏幕分辨率,进行绘图时会因为原有屏幕缓存大小与现有不符而崩溃。可重启程序解决。
The text was updated successfully, but these errors were encountered: