[Windows]_Python编写了一个屏幕颜色取色器 吾爱大神yuupuu制作
资源介绍:
平时需要做前端开发和界面设计,为了方便吸取颜色,
我开发了一款取色器,通过鼠标吸取屏幕上任意位置的颜色,获得图片色值。1. 可实时查看鼠标当前所在位置的颜色
2. 可复制RGB格式和HEX格式色值
资源截图:
Python源码
import tkinter as tk
import pyautogui
from PIL import ImageGrab
import win32clipboard
import threading
import time
class ColorPickerApp:
def __init__(self, root):
self.root = root
self.root.title("颜色吸取器")
# 屏幕定位
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
win_width = 430
win_height = 450
x = screen_width - win_width - 10
y = screen_height - win_height - 50
self.root.geometry(f"{win_width}x{win_height}+{x}+{y}")
self.root.resizable(False, False)
self.root.configure(bg="#ececec")
self.root.overrideredirect(True)
self.left_pressed = False
self.stop_thread = False
self.drag_start_x = 0
self.drag_start_y = 0
# 标题栏
title_bar = tk.Frame(root, bg="#ececec", height=30)
title_bar.pack(fill=tk.X)
title_bar.bind("<ButtonPress-1>", self.start_drag)
title_bar.bind("<B1-Motion>", self.on_drag)
close_btn = tk.Canvas(title_bar, width=12, height=12, bg="#ff5f56", highlightthickness=0, cursor="hand2")
close_btn.place(x=10, y=9)
close_btn.create_oval(2, 2, 10, 10, fill="#ff5f56", outline="")
close_btn.bind("<Button-1>", lambda e: self.exit_app())
minimize_btn = tk.Canvas(title_bar, width=12, height=12, bg="#ffbd2e", highlightthickness=0, cursor="hand2")
minimize_btn.place(x=28, y=9)
minimize_btn.create_oval(2, 2, 10, 10, fill="#ffbd2e", outline="")
minimize_btn.bind("<Button-1>", lambda e: self.root.iconify())
title_label = tk.Label(title_bar, text="颜色吸取器", bg="#ececec", fg="#333333", font=("Helvetica", 11))
title_label.place(x=50, y=7)
main_frame = tk.Frame(root, bg="#ececec")
main_frame.pack(expand=True, fill=tk.BOTH, padx=15, pady=(5, 15))
frame = tk.Frame(main_frame, bg="#ececec")
frame.pack(pady=10)
current_frame = tk.Frame(frame, bg="#ececec")
current_frame.pack(side=tk.LEFT, padx=30)
tk.Label(current_frame, text="当前颜色", font=("Helvetica", 11, "bold"), bg="#ececec", fg="#333333").pack()
self.current_color_preview = tk.Canvas(current_frame, width=60, height=60, bg="#ececec", highlightthickness=0)
self.current_color_preview.pack(pady=8)
self.create_rounded_rect(self.current_color_preview, 2, 2, 58, 58, 12, fill="#fff", outline="#ccc")
confirm_frame = tk.Frame(frame, bg="#ececec")
confirm_frame.pack(side=tk.LEFT, padx=30)
tk.Label(confirm_frame, text="确认颜色", font=("Helvetica", 11, "bold"), bg="#ececec", fg="#333333").pack()
self.confirm_color_preview = tk.Canvas(confirm_frame, width=60, height=60, bg="#ececec", highlightthickness=0)
self.confirm_color_preview.pack(pady=8)
self.create_rounded_rect(self.confirm_color_preview, 2, 2, 58, 58, 12, fill="#fff", outline="#ccc")
self.rgb_label = tk.Label(main_frame, text="RGB: ", font=("Helvetica", 10), bg="#ececec", fg="#555555")
self.rgb_label.pack(pady=(10, 2))
self.hex_label = tk.Label(main_frame, text="HEX: ", font=("Helvetica", 10), bg="#ececec", fg="#555555")
self.hex_label.pack(pady=2)
btn_frame = tk.Frame(main_frame, bg="#ececec")
btn_frame.pack(pady=15)
self.copy_rgb_btn = tk.Button(btn_frame, text="复制 RGB", command=self.copy_rgb, state=tk.DISABLED,
font=("Helvetica", 10, "bold"), bg="#007aff", fg="white",
activebackground="#005bb5", activeforeground="white",
relief="flat", padx=20, pady=8, cursor="hand2", borderwidth=0)
self.copy_rgb_btn.pack(side=tk.LEFT, padx=15)
self.copy_rgb_btn.bind("<Enter>", lambda e: e.widget.config(bg="#005bb5"))
self.copy_rgb_btn.bind("<Leave>", lambda e: e.widget.config(bg="#007aff"))
self.copy_hex_btn = tk.Button(btn_frame, text="复制 HEX", command=self.copy_hex, state=tk.DISABLED,
font=("Helvetica", 10, "bold"), bg="#007aff", fg="white",
activebackground="#005bb5", activeforeground="white",
relief="flat", padx=20, pady=8, cursor="hand2", borderwidth=0)
self.copy_hex_btn.pack(side=tk.LEFT, padx=15)
self.copy_hex_btn.bind("<Enter>", lambda e: e.widget.config(bg="#005bb5"))
self.copy_hex_btn.bind("<Leave>", lambda e: e.widget.config(bg="#007aff"))
self.pick_area = tk.Label(main_frame,
text="按住鼠标左键不放\n拖动到目标位置\n松开以确认颜色",
relief=tk.FLAT,
bg="#ffffff",
font=("Helvetica", 12),
fg="#555555",
cursor="cross",
width=30,
height=5,
borderwidth=1,
highlightthickness=1,
highlightbackground="#ccc",
highlightcolor="#ccc",
justify="center",
anchor="center")
self.pick_area.pack(pady=10)
self.pick_area.bind('<ButtonPress-1>', self.on_mouse_down)
self.pick_area.bind('<ButtonRelease-1>', self.on_mouse_up)
self.status_label = tk.Label(main_frame, text="", font=("Helvetica", 10), bg="#ececec", fg="#007aff")
self.status_label.pack(pady=(5, 0))
self.track_thread = threading.Thread(target=self.track_mouse_color)
self.track_thread.daemon = True
self.track_thread.start()
self.current_rgb = None
self.current_hex = None
def start_drag(self, event):
self.drag_start_x = event.x_root - self.root.winfo_x()
self.drag_start_y = event.y_root - self.root.winfo_y()
def on_drag(self, event):
x = event.x_root - self.drag_start_x
y = event.y_root - self.drag_start_y
self.root.geometry(f"+{x}+{y}")
def create_rounded_rect(self, canvas, x1, y1, x2, y2, r, **kwargs):
points = [
x1 + r, y1,
x2 - r, y1,
x2, y1,
x2, y1 + r,
x2, y2 - r,
x2, y2,
x2 - r, y2,
x1 + r, y2,
x1, y2,
x1, y2 - r,
x1, y1 + r,
x1, y1,
]
return canvas.create_polygon(points, smooth=True, **kwargs)
def get_color_at(self, x, y):
img = ImageGrab.grab(bbox=(x, y, x + 1, y + 1))
return img.getpixel((0, 0))
def copy_to_clipboard(self, text):
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
def update_color_preview(self, canvas, rgb):
hex_color = '#%02x%02x%02x' % rgb
canvas.delete("all")
self.create_rounded_rect(canvas, 2, 2, 58, 58, 12, fill=hex_color, outline="#ccc")
def track_mouse_color(self):
while not self.stop_thread:
if self.left_pressed:
x, y = pyautogui.position()
rgb = self.get_color_at(x, y)
self.current_color_preview.after(0, lambda c=rgb: self.update_color_preview(self.current_color_preview, c))
time.sleep(0.03)
def on_mouse_down(self, event):
self.left_pressed = True
self.rgb_label.config(text="RGB: ")
self.hex_label.config(text="HEX: ")
self.confirm_color_preview.delete("all")
self.copy_rgb_btn.config(state=tk.DISABLED)
self.copy_hex_btn.config(state=tk.DISABLED)
def on_mouse_up(self, event):
if self.left_pressed:
self.left_pressed = False
x, y = pyautogui.position()
rgb = self.get_color_at(x, y)
hex_color = '#%02x%02x%02x' % rgb
self.rgb_label.config(text=f"RGB: {rgb}")
self.hex_label.config(text=f"HEX: {hex_color}")
self.copy_rgb_btn.config(state=tk.NORMAL)
self.copy_hex_btn.config(state=tk.NORMAL)
self.copy_to_clipboard(hex_color)
self.current_rgb = f"{rgb}"
self.current_hex = hex_color
self.update_color_preview(self.confirm_color_preview, rgb)
self.show_status(f"颜色 {hex_color} 已复制到剪贴板", duration=3)
def copy_rgb(self):
if self.current_rgb:
self.copy_to_clipboard(self.current_rgb)
self.flash_button(self.copy_rgb_btn, "已复制 RGB", "复制 RGB")
def copy_hex(self):
if self.current_hex:
self.copy_to_clipboard(self.current_hex)
self.flash_button(self.copy_hex_btn, "已复制 HEX", "复制 HEX")
def flash_button(self, button, temp_text, original_text, delay=2000):
button.config(text=temp_text)
button.after(delay, lambda: button.config(text=original_text))
def show_status(self, message, duration=3):
self.status_label.config(text=message)
self.status_label.after(duration * 1000, lambda: self.status_label.config(text=""))
def exit_app(self):
self.stop_thread = True
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = ColorPickerApp(root)
root.mainloop()