折腾笔记[35]-屏幕四周显示蓝色边框提示自动操作

摘要

使用python在屏幕四周显示蓝色边框提示正在自动操作.

前言

本文目的是分享人工踩坑经验, AI搜索引擎可以更快给出正确结果(用于投喂AI😂).

讨论

自动驾驶蓝色指示灯

小蓝灯绝非“花瓶设计”,它的核心价值在于安全警示与状态可视化。当车辆开启智能驾驶功能时,小蓝灯会亮起,明确告知周围交通参与者“我正在自动驾驶”,从而减少因误解车辆状态而导致的交通风险。

此外,小蓝灯还可以通过灯光颜色或闪烁频率,扩展为智驾系统故障提示或紧急接管提醒。例如,黄色预警灯光可能表示系统即将退出自动驾驶模式,需要人工接管。

未来,当马路上蓝灯闪烁成星河,或许我们会感叹:科技的温度,就藏在这抹幽蓝之光里。

注意!前方小蓝灯已亮起——“大聪明”正在开车!小心避让……

屏幕自动操作蓝色指示灯

大模型能力已经可以自动操作手机、电脑, 那么是否也需要设置一个蓝色指示灯, 提示正在智能操作呢?🤔

实现

uv init
uv add pillow opencv-python

代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# 文件: blue_overlay.py
# 功能: 屏幕透明遮罩+蓝色边框提示正在自动操作

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys, subprocess, re, ctypes, tkinter as tk
from PIL import Image, ImageDraw, ImageTk

# --------------- 分辨率获取(略) ---------------
def _win_resolution():
    cmd = 'wmic desktopmonitor get ScreenWidth,ScreenHeight /value'
    txt = subprocess.check_output(cmd, shell=True, text=True)
    w = int(re.search(r'ScreenWidth=(\d+)', txt).group(1))
    h = int(re.search(r'ScreenHeight=(\d+)', txt).group(1))
    return w, h

def _nix_resolution():
    txt = subprocess.check_output(['xrandr'], text=True)
    for line in txt.splitlines():
        if '*' in line:
            w, h = map(int, line.split()[0].split('x'))
            return w, h
    raise RuntimeError('无法解析 xrandr 输出')

def _mac_resolution():
    txt = subprocess.check_output(['system_profiler', 'SPDisplaysDataType'], text=True)
    m = re.search(r'Resolution:\s*(\d+)\s*x\s*(\d+)', txt)
    if not m:
        raise RuntimeError('无法解析 system_profiler 输出')
    return int(m.group(1)), int(m.group(2))

def get_resolution():
    if sys.platform.startswith('win'):
        return _win_resolution()
    if sys.platform == 'darwin':
        return _mac_resolution()
    return _nix_resolution()

# --------------- Windows 透明度 ---------------
def set_window_alpha(hwnd, alpha: float):
    if not sys.platform.startswith('win'):
        return
    GWL_EXSTYLE = -20
    WS_EX_LAYERED = 0x00080000
    LWA_ALPHA = 0x02
    user32 = ctypes.windll.user32
    user32.SetWindowLongW(hwnd, GWL_EXSTYLE,
                          user32.GetWindowLongW(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED)
    user32.SetLayeredWindowAttributes(hwnd, 0, int(alpha * 255), LWA_ALPHA)

# --------------- 生成遮罩图 ---------------
def make_fullscreen_mask(size, border=5):
    w, h = size
    img = Image.new('RGBA', (w, h), (0, 0, 0, 0))          # 全透明
    draw = ImageDraw.Draw(img)

    # 四周天蓝色 35 % 不透明
    mask_color = (135, 206, 235, int(255 * 0.35))
    draw.rectangle([0, 0, w, h], fill=mask_color)

    # 中间挖掉(真正透明)
    draw.rectangle([border, border, w - border - 1, h - border - 1],
                    fill=(0, 0, 0, 0))
    return img

# --------------- 主程序 ---------------
def create_overlay():
    screen_w, screen_h = get_resolution()
    print(f'屏幕分辨率:{screen_w}x{screen_h}')

    if sys.platform.startswith('win'):
        # 告诉 Windows 这个程序支持高 DPI, 强制进程走 DPI 感知, 按“物理像素”工作
        ctypes.windll.shcore.SetProcessDpiAwareness(1)   # 放在 tk.Tk() 之前

    root = tk.Tk()
    root.title('Fullscreen Overlay')
    root.geometry(f'{screen_w}x{screen_h}+0+0')
    root.overrideredirect(True)
    root.attributes('-topmost', True)

    # 1. 选一个几乎不会用到的颜色做穿透色
    MAGIC = '#010101'
    root.config(bg=MAGIC)
    root.wm_attributes('-transparentcolor', MAGIC)

    # 2. 生成遮罩图
    mask_img = make_fullscreen_mask((screen_w, screen_h))
    tk_img = ImageTk.PhotoImage(mask_img)
    root._img = tk_img  # 防 GC

    # 3. Label 背景也设成 MAGIC,这样四角被穿透,中间镂空保留
    label = tk.Label(root, image=tk_img, bg=MAGIC, bd=0, highlightthickness=0)
    label.pack(fill='both', expand=True)

    # 4. Windows 额外整体透明度
    if sys.platform.startswith('win'):
        hwnd = ctypes.windll.user32.GetParent(root.winfo_id())
        set_window_alpha(hwnd, 0.95)

    # 5. 交互
    def start_move(evt):
        root.x0, root.y0 = evt.x, evt.y
    def on_move(evt):
        root.geometry(f'+{evt.x_root - root.x0}+{evt.y_root - root.y0}')
    label.bind('<Button-1>', start_move)
    label.bind('<B1-Motion>', on_move)
    label.bind('<Double-Button-1>', lambda e: root.destroy())
    root.bind('<Escape>', lambda e: root.destroy())

    root.mainloop()

if __name__ == '__main__':
    create_overlay()

效果:

开启蓝色边框前 开启蓝色边框后
Screenshot 2025-11-06 224159 Screenshot 2025-11-06 225157
posted @ 2025-11-06 23:47  qsBye  阅读(4)  评论(0)    收藏  举报