新手 Python 求教

31 天前
 life90

  代码如下:

import tkinter as tk
import win32api
import win32con
import pywintypes
from screeninfo import get_monitors
from PIL import Image, ImageDraw, ImageFont,ImageTk

font_family = "msyh.ttf"  # Replace with your actual font filename
font_size = 36
def generate_watermark(text, width, height, color='#d5d5d5', opacity=10, lines=1, angle=0):

    spacing = 10
    # 创建一个 Image 对象,用于绘制水印
    img = Image.new('RGBA', (width, height), (255, 255, 255, 0))
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype(font_family, font_size)

    # 将文本拆分成多行
    text_lines = text.split('\n')

    # 计算每个水印的宽度和高度
    bbox = draw.textbbox((0, 0), text_lines[0], font=font)
    text_width, text_height = bbox[2] - bbox[0], bbox[3] - bbox[1] + 30

    # 计算每行可以容纳的水印数量
    watermarks_per_row = width // (text_width + spacing)
    total_rows = (height - 50) // (text_height + spacing)
    # 设置初始位置
    x = 50
    y = 50

    for row in range(total_rows):
        x = 50  # 每行重新从左侧开始
        y = 50 + row * (text_height + spacing)

        for col in range(watermarks_per_row):
            # 旋转文本

            rotated_text = Image.new('RGBA', (text_width, text_height), (255, 255, 255, 0))
            rotated_draw = ImageDraw.Draw(rotated_text)

            if row < len(text_lines):
                rotated_draw.text((0, 0), text_lines[row], font=font, fill=color)
            else:
                # 如果 row 超出范围,跳过绘制
                break
            rotated_text = rotated_text.rotate(angle, expand=True)

            # 将旋转后的文本粘贴到主图像上
            img.paste(rotated_text, (x, y), rotated_text)
            x += text_width + spacing

    tk_img = ImageTk.PhotoImage(img)

    # 创建一个 Label 并显示图片
    label = tk.Label(image=tk_img,bg="white")
    label.image = tk_img  # 保持引用,防止垃圾回收
    label.pack()

def get_total_screen_size():
    monitors = get_monitors()
    width = sum(monitor.width for monitor in monitors)
    height = max(monitor.height for monitor in monitors)
    return width, height

def create_watermark_window(text, **kwargs):

    root = tk.Tk()
    # 获取屏幕分辨率
    screen_width, screen_height = get_total_screen_size()
    def generate_watermark_with_size():
        generate_watermark(text, screen_width, screen_height, **kwargs)

    # 使用 after 方法延迟执行生成水印函数
    root.after(100, generate_watermark_with_size)
    root.overrideredirect(True)
    root.lift()
    root.attributes('-alpha', 0.2)  # 设置透明度
    root.wm_attributes('-topmost', True)
    root.wm_attributes('-disabled', True)
    root.wm_attributes('-transparentcolor',"white")
    hWindow = pywintypes.HANDLE(int(root.frame(), 16))
    exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT
    win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle)
    root.mainloop()

if __name__ == '__main__':
    mytext = "一二\n 二行"
    angle = 45  # 旋转角度
    create_watermark_window(mytext, angle=angle, lines=10)

  我想实现全屏水印,但是只实现了一行。   对于计算,实在脑袋不够用,恳请各位赐教一下

1605 次点击
所在节点    Python
6 条回复
lpe234
31 天前
```python
if row < len(text_lines):
rotated_draw.text((0, 0), text_lines[row], font=font, fill=color)
else:
# 如果 row 超出范围,跳过绘制
break
```
这块写的有问题,只会绘制 text_lines 行数。 改成下面的就好了 `rotated_draw.text((0, 0), text_lines[row % len(text_lines)], font=font, fill=color)`
life90
31 天前
@lpe234 按你的改了,也不行。显示效果如图:

![python 显示效果]( https://s21.ax1x.com/2024/11/28/pA59my4.png)

这是个扩展屏,总的长高是 3840 * 1200
life90
31 天前
lpe234
31 天前
@life90 #2 不会呀




----
# if row < len(text_lines):
# rotated_draw.text((0, 0), text_lines[row], font=font, fill=color)
# else:
# # 如果 row 超出范围,跳过绘制
# break
# Here
rotated_draw.text((0, 0), text_lines[row % len(text_lines)], font=font, fill=color)
----
life90
31 天前
@lpe234 感谢,我好像明白了。他是根据 \n 来划分行数的。修改这个值就行。
life90
30 天前
@lpe234 你知道如何处理扩展屏的状态么?在扩展屏来回切换,会导致只有一屏显示。
```
iimport tkinter as tk
import win32api
import win32con
import pywintypes
import os
import threading
import time
from screeninfo import get_monitors
from PIL import Image, ImageDraw, ImageFont,ImageTk

def get_total_screen_size():
monitors = get_monitors()
width = sum(monitor.width for monitor in monitors)
height = max(monitor.height for monitor in monitors)
return width, height

font_family = "msyh.ttf" # Replace with your actual font filename
font_size = 36
def generate_watermark(text, width, height,color='#d5d5d5', opacity=0, lines=10, angle=0):

get_total_screen_size()
spacing = 100
# 创建一个 Image 对象,用于绘制水印
img = Image.new('RGBA', (width, height), (255, 255, 255, 0))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(font_family, font_size)

# 将文本拆分成多行
text_lines = text.split('\n') if text else lines

# 计算每个水印的宽度和高度
bbox = draw.textbbox((0, 0), text_lines[0], font=font)
text_width, text_height = bbox[2] - bbox[0] + spacing, bbox[3] - bbox[1] + spacing

# 计算每行可以容纳的水印数量
watermarks_per_row = width // (text_width + spacing)
total_rows = (height - 50) // (text_height + spacing)
# 设置初始位置
x = 50
y = 30

for row in range(0,total_rows):
x = 50 # 每行重新从左侧开始
y = 50 + row * (text_height + spacing)

for col in range(0,watermarks_per_row):

rotated_text = Image.new('RGBA', (text_width, text_height), (255, 255, 255, 0))
rotated_draw = ImageDraw.Draw(rotated_text)
rotated_draw.text((0, 0), text_lines[row % len(text_lines)], font=font, fill=color)
rotated_text = rotated_text.rotate(angle, expand=True)
# 将旋转后的文本粘贴到主图像上
img.paste(rotated_text, (x, y), rotated_text)
x += text_width + spacing

tk_img = ImageTk.PhotoImage(img)
# 创建一个 Label 并显示图片
label = tk.Label(image=tk_img,bg="white")
label.image = tk_img # 保持引用,防止垃圾回收
label.pack()


def create_watermark_window(text, **kwargs):

root = tk.Tk()

def generate_watermark_with_size():
screen_width, screen_height = get_total_screen_size()
generate_watermark(text, screen_width, screen_height, **kwargs)

def monitor_resolution_changes():
nonlocal generate_watermark_with_size
prev_monitor_count = 1
while True:
current_monitor_count = len(get_monitors())
if current_monitor_count != prev_monitor_count:
generate_watermark_with_size()
prev_monitor_count = current_monitor_count
time.sleep(3)

monitor_thread = threading.Thread(target=monitor_resolution_changes)
monitor_thread.daemon = True
monitor_thread.start()
# 使用 after 方法延迟执行生成水印函数
root.after(100, generate_watermark_with_size)
root.overrideredirect(True)
root.lift()
root.attributes('-alpha', 0.3) # 设置透明度
root.wm_attributes('-topmost', True)
root.wm_attributes('-disabled', True)
root.wm_attributes('-transparentcolor',"white")
hWindow = pywintypes.HANDLE(int(root.frame(), 16))
exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT
win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle)
root.mainloop()

# 使用示例
if __name__ == '__main__':
# 获取当前用户名
username = os.getlogin()
# 组合文本
mytext = f"Allianz\n{username}" # 使用 f-string 格式化字符串
angle = 45 # 旋转角度
create_watermark_window(mytext, angle=angle, lines=10)
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1093360

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX