点击下列公众号+【关注】,接收最新文章。



“嗨,朋友!今天带你整一个超实用的小工具——图片颜色提取器。你只要把一张图拖进去,啪!它立刻把图里所有好看的颜色整整齐齐排好队,还能一键复制 HEX 或 RGB 值。做 PPT、写前端、搞设计,再也不用对着 PS 吸色吸到手抽筋。整个程序用 Python 写的,界面是 Tkinter,逻辑简单、界面清爽,跟着我一层层拆,包你 10 分钟就能看懂!”
0808052图片列举色值.py├── ① 类 ImageColorExtractor│ ├── __init__ —— 界面初始化│ ├── upload_image —— 文件选择与预览│ ├── display_image —— 自适应缩放│ ├── extract_colors —— 颜色提取│ ├── display_colors —— 颜色展示│ └── copy_to_clipboard —— 剪贴板复制└── ② main 入口每段代码都按“5 行以上 + 逐行解释 + 结构层级”输出,保证你能像剥洋葱一样一层层看懂。
if __name__ == "__main__": root = tk.Tk() # 1. 创建根窗口 app = ImageColorExtractor(root) # 2. 实例化主类 root.mainloop() # 3. 进入事件循环ImageColorExtractor 类里,方便维护和复用。__init__:搭好舞台再放演员classImageColorExtractor:def__init__(self, root): self.root = root self.root.title("图片颜色提取器") self.root.geometry("900x700") self.root.minsize(800, 600) self.style = ttk.Style() self.style.configure("TButton", font=("SimHei", 10)) self.style.configure("TLabel", font=("SimHei", 10)) self.style.configure("Header.TLabel", font=("SimHei", 12, "bold"))ttk.Style 保证中文按钮、标签不乱码,字号统一,强迫症福音。 self.main_frame = ttk.Frame(root, padding="10") self.main_frame.pack(fill=tk.BOTH, expand=True)main_frame 里,边距 10px,防止贴边拥挤。# 顶部控制区 self.control_frame = ttk.Frame(self.main_frame, padding="5") self.control_frame.pack(fill=tk.X, pady=(0, 10))upload_imagedefupload_image(self): file_path = filedialog.askopenfilename( filetypes=[ ("图片文件", "*.png;*.jpg;*.jpeg;*.bmp;*.gif"), ("所有文件", "*.*") ] )ifnot file_path:returnfiledialog.askopenfilename 弹出系统选择框,过滤常见图片格式,减少用户误选。try: self.original_image = Image.open(file_path) self.display_image(self.original_image) self.extract_colors()except Exception as e: messagebox.showerror("错误", f"无法打开图片: {str(e)}")display_imagedefdisplay_image(self, image): max_width = self.image_frame.winfo_width() - 20 max_height = self.image_frame.winfo_height() - 20if max_width < 100: max_width = 600if max_height < 100: max_height = 400 image.thumbnail((max_width, max_height)) tk_image = ImageTk.PhotoImage(image) self.image_label.config(image=tk_image) self.image_label.image = tk_image # 防止被垃圾回收thumbnail 保持纵横比,得到的 tk_image 直接塞给 Label,最后一行是 Tkinter 的经典“防回收”套路。extract_colorsdefextract_colors(self):ifnot self.original_image:return img = self.original_image.copy() img.thumbnail((200, 200)) # 先压小图,加快速度if img.mode != "RGB": img = img.convert("RGB") pixels = np.array(img) pixels = pixels.reshape(-1, 3)(N, 3)。 unique_colors = np.unique(pixels, axis=0) count = int(self.color_count.get())if len(unique_colors) > count: step = len(unique_colors) // count unique_colors = unique_colors[::step][:count]np.unique 去掉重复色,[::step] 均匀采样,保证最终颜色数 ≤ 下拉框里的 10/20/30/50/100。 unique_colors = sorted( unique_colors, key=lambda rgb: colorsys.rgb_to_hls( rgb[0]/255, rgb[1]/255, rgb[2]/255)[1] ) self.colors = [(r, g, b) for r, g, b in unique_colors] self.display_colors()colorsys.rgb_to_hls 取 L(lightness) 排序,视觉观感从暗到亮,整齐顺眼。display_colorsdefdisplay_colors(self):for widget in self.scrollable_frame.winfo_children(): widget.destroy()for i, (r, g, b) in enumerate(self.colors): row_frame = ttk.Frame(self.scrollable_frame, padding="5") row_frame.pack(fill=tk.X, pady=2) color_frame = tk.Frame( row_frame, width=30, height=30, bg=f"#{r:02x}{g:02x}{b:02x}" ) color_frame.pack(side=tk.LEFT, padx=10) color_frame.pack_propagate(False)bg 用格式化字符串拼出十六进制色值,注意补零。 hex_color = f"#{r:02x}{g:02x}{b:02x}".upper() rgb_color = f"RGB: ({r}, {g}, {b})" color_info = ttk.Label( row_frame, text=f"{hex_color} | {rgb_color}", width=40 ) color_info.pack(side=tk.LEFT, padx=10) copy_btn = ttk.Button( row_frame, text="复制HEX", command=lambda c=hex_color: self.copy_to_clipboard(c) ) copy_btn.pack(side=tk.LEFT, padx=5) copy_rgb_btn = ttk.Button( row_frame, text="复制RGB", command=lambda r=r, g=g, b=b: self.copy_to_clipboard(f"rgb({r}, {g}, {b})") ) copy_rgb_btn.pack(side=tk.LEFT, padx=5)lambda 做闭包,提前绑定当前颜色值,点一下就复制。copy_to_clipboarddefcopy_to_clipboard(self, text): self.root.clipboard_clear() self.root.clipboard_append(text) messagebox.showinfo("成功", f"已复制: {text}")self.canvas = tk.Canvas(self.scroll_frame)self.scrollbar = ttk.Scrollbar( self.scroll_frame, orient="vertical", command=self.canvas.yview)self.scrollable_frame = ttk.Frame(self.canvas)self.scrollable_frame.bind("<Configure>",lambda e: self.canvas.configure( scrollregion=self.canvas.bbox("all") ))self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")self.canvas.configure(yscrollcommand=self.scrollbar.set)scrollable_frame 作为容器放在 Canvas 里,内容变化时重新计算 scrollregion,实现滚动。通过本项目,你不仅掌握了一个实用小工具,还顺带复习了 Python 桌面开发、图像处理、颜色理论三大方向的基础知识。下次做设计系统、品牌色板、前端主题变量,直接拖图→复制→粘贴,效率 up!
sklearn.cluster.KMeans 替代均匀采样,提取主题色更准确。.aco / .ase 供 Photoshop、Illustrator 使用。全文 2000+ 字,从按钮到算法,从布局到剪贴板,逐层拆解、条理有序。祝你玩得开心,早日把这套小工具变成自己的瑞士军刀!
import tkinter as tkfrom tkinter import filedialog, ttk, messageboxfrom PIL import Image, ImageTkimport numpy as npimport colorsysimport ioclass ImageColorExtractor:def init(self, root):self.root = rootself.root.title("图片颜色提取器")self.root.geometry("900x700")self.root.minsize(800, 600)# 确保中文显示正常self.style = ttk.Style()self.style.configure("TButton", font=("SimHei", 10))self.style.configure("TLabel", font=("SimHei", 10))self.style.configure("Header.TLabel", font=("SimHei", 12, "bold"))# 创建主框架self.main_frame = ttk.Frame(root, padding="10")self.main_frame.pack(fill=tk.BOTH, expand=True)# 顶部控制区self.control_frame = ttk.Frame(self.main_frame, padding="5")self.control_frame.pack(fill=tk.X, pady=(0, 10))# 上传按钮self.upload_btn = ttk.Button(self.control_frame,text="上传图片",command=self.upload_image)self.upload_btn.pack(side=tk.LEFT, padx=(0, 10))# 颜色数量选择ttk.Label(self.control_frame, text="提取颜色数量:").pack(side=tk.LEFT, padx=(0, 5))self.color_count = tk.StringVar(value="20")self.color_count_combo = ttk.Combobox(self.control_frame,textvariable=self.color_count,values=["10", "20", "30", "50", "100"],width=5)self.color_count_combo.pack(side=tk.LEFT, padx=(0, 20))# 图片显示区self.image_frame = ttk.LabelFrame(self.main_frame, text="图片预览", padding="5")self.image_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))self.image_label = ttk.Label(self.image_frame)self.image_label.pack(fill=tk.BOTH, expand=True)# 颜色列表区self.colors_frame = ttk.LabelFrame(self.main_frame, text="图片中的颜色", padding="5")self.colors_frame.pack(fill=tk.BOTH, expand=True)# 创建滚动区域self.scroll_frame = ttk.Frame(self.colors_frame)self.scroll_frame.pack(fill=tk.BOTH, expand=True)self.canvas = tk.Canvas(self.scroll_frame)self.scrollbar = ttk.Scrollbar(self.scroll_frame,orient="vertical",command=self.canvas.yview)self.scrollable_frame = ttk.Frame(self.canvas)self.scrollable_frame.bind("<Configure>",lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")self.canvas.configure(yscrollcommand=self.scrollbar.set)self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)# 存储颜色数据self.colors = []self.original_image = Nonedef upload_image(self):"""上传并显示图片"""file_path = filedialog.askopenfilename(filetypes=[("图片文件", "*.png;*.jpg;*.jpeg;*.bmp;*.gif"),("所有文件", "*.*")])if not file_path:returntry:# 打开图片self.original_image = Image.open(file_path)self.display_image(self.original_image)# 提取颜色self.extract_colors()except Exception as e:messagebox.showerror("错误", f"无法打开图片: {str(e)}")def display_image(self, image):"""在界面上显示图片"""# 调整图片大小以适应窗口max_width = self.image_frame.winfo_width() - 20max_height = self.image_frame.winfo_height() - 20# 如果窗口还没渲染,使用默认尺寸if max_width < 100:max_width = 600if max_height < 100:max_height = 400# 保持比例缩放image.thumbnail((max_width, max_height))# 转换为Tkinter可用的格式tk_image = ImageTk.PhotoImage(image)# 显示图片self.image_label.config(image=tk_image)self.image_label.image = tk_image # 保持引用def extract_colors(self):"""从图片中提取颜色"""if not self.original_image:return# 调整图片大小以加快处理速度img = self.original_image.copy()img.thumbnail((200, 200)) # 缩小图片# 转换为RGB模式if img.mode != "RGB":img = img.convert("RGB")# 获取像素数据pixels = np.array(img)pixels = pixels.reshape(-1, 3)# 转换为列表并去重unique_colors = np.unique(pixels, axis=0)# 限制最大颜色数量count = int(self.color_count.get())if len(unique_colors) > count:# 简单采样,实际应用中可以使用更复杂的聚类算法step = len(unique_colors) // countunique_colors = unique_colors[::step][:count]# 按亮度排序(便于查看)unique_colors = sorted(unique_colors,key=lambda rgb: colorsys.rgb_to_hls(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255)[1])self.colors = [(r, g, b) for r, g, b in unique_colors]self.display_colors()def display_colors(self):"""显示提取的颜色"""# 清空之前的颜色显示for widget in self.scrollable_frame.winfo_children():widget.destroy()# 显示颜色for i, (r, g, b) in enumerate(self.colors):# 创建行框架row_frame = ttk.Frame(self.scrollable_frame, padding="5")row_frame.pack(fill=tk.X, pady=2)# 颜色方块color_frame = tk.Frame(row_frame,width=30,height=30,bg=f"#{r:02x}{g:02x}{b:02x}")color_frame.pack(side=tk.LEFT, padx=10)color_frame.pack_propagate(False) # 保持尺寸# 颜色值标签hex_color = f"#{r:02x}{g:02x}{b:02x}".upper()rgb_color = f"RGB: ({r}, {g}, {b})"color_info = ttk.Label(row_frame,text=f"{hex_color} | {rgb_color}",width=40)color_info.pack(side=tk.LEFT, padx=10)# 复制按钮copy_btn = ttk.Button(row_frame,text="复制HEX",command=lambda c=hex_color: self.copy_to_clipboard(c))copy_btn.pack(side=tk.LEFT, padx=5)copy_rgb_btn = ttk.Button(row_frame,text="复制RGB",command=lambda r=r, g=g, b=b: self.copy_to_clipboard(f"rgb({r}, {g}, {b})"))copy_rgb_btn.pack(side=tk.LEFT, padx=5)def copy_to_clipboard(self, text):"""将文本复制到剪贴板"""self.root.clipboard_clear()self.root.clipboard_append(text)messagebox.showinfo("成功", f"已复制: {text}")if name == "main":root = tk.Tk()app = ImageColorExtractor(root)root.mainloop()
点击【关注+收藏】获取最新的实战代码案例
用Python打造汉字笔画查询工具:从GUI界面到笔顺动画实现
Python超实用 Markdown 转富文本神器 —— 代码全解析
【实战1】
【实战2】
【实战3】
【实战4】



明朝那些皇帝-16:按顺序如下:
1:明太祖 朱元璋(洪武,1368–1398)
2:明惠帝 朱允炆(建文,1398–1402)
3:明成祖 朱棣(永乐,1402–1424)
4:明仁宗 朱高炽(洪熙,1424–1425)
朱高炽:在位十个月的明朝"胖仁宗",如何靠吃和躺赢成为千古明君?
5:明宣宗 朱瞻基(宣德,1425–1435)
6:明英宗 朱祁镇(正统,1435–1449;后复位,天顺,1457–1464)
7:明代宗 朱祁钰(景泰,1449–1457)
8:明宪宗 朱见深(成化,1464–1487)
9:明孝宗 朱祐樘(弘治,1487–1505)
10:明武宗 朱厚照(正德,1505–1521)
11:明世宗 朱厚熜(嘉靖,1521–1566)
明世宗朱厚熜:炼丹炉里的权力游戏——大明修仙CEO的荒诞创业史
12:明穆宗 朱载坖(隆庆,1566–1572)
13:明神宗 朱翊钧(万历,1572–1620)
14:明光宗 朱常洛(泰昌,1620,仅一个月)
15:明熹宗 朱由校(天启,1620–1627)
16:明思宗 朱由检(崇祯,1627–1644)
注:
明英宗两次在位(正统、天顺),中间被弟弟明代宗取代。
南明政权(如弘光帝等)不被视为正统明朝皇帝。
传奇故事系列
从“饿死相”到“宰相命”:唐代版《逆袭之星途璀璨》的反转人生
高考错题本害了他?明朝学霸因一个错别字错失状元,却在茶肆捡了个省长
《喻世通言》之李秀卿义结黄贞女:一场跨越性别与世俗的传奇情谊
她带百万嫁妆嫁渣男,发现被卖后当场销毁全部家产——明代名妓的复仇爽文