V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
life90
V2EX  ›  Python

新手 Python 求教

  •  
  •   life90 · 31 天前 · 1605 次点击

      代码如下:

    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)
    

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

    6 条回复    2024-11-29 16:36:52 +08:00
    lpe234
        1
    lpe234  
       31 天前   ❤️ 1
    ```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
        2
    life90  
    OP
       31 天前
    @lpe234 按你的改了,也不行。显示效果如图:

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

    这是个扩展屏,总的长高是 3840 * 1200
    life90
        3
    life90  
    OP
       31 天前
    lpe234
        4
    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
        5
    life90  
    OP
       31 天前
    @lpe234 感谢,我好像明白了。他是根据 \n 来划分行数的。修改这个值就行。
    life90
        6
    life90  
    OP
       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)
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2872 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 13:57 · PVG 21:57 · LAX 05:57 · JFK 08:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.