文章背景:工作中,有时候需要判断图片中不同位置的颜色。有些颜色不太容易区分,所以想通过Python编写代码,通过屏幕取点,获取某个位置的颜色值。
代码逻辑:
(1)文末参考资料[2]
的csv文件(记为颜色表
)中给出了865种颜色的英文名称和对应的RGB数值,在此基础上,笔者添加了相应的中文名称,如下表所示。
(2)通过鼠标在屏幕上取点,获取指定位置的RGB数值,然后与颜色表
中各行的RGB数值进行匹配,返回RGB数值最接近的颜色信息。
Python代码:
# Python实现屏幕取色器功能
# adapted form https://mp.weixin.qq.com/s/S_FNIqtqdvlEgplM7UuvNg
import os
import pandas as pd
from time import sleep
from PIL import ImageGrab, Image
import uuid
import pyperclip
import tkinter
import tkinter.messagebox
def get_color_name(r, g, b, csv_df):
# 基于给定的R,G,B和颜色表,匹配与所取点RGB数值最接近的颜色。
min_diff = 10000
color = ["" for i in range(6)]
for i in range(len(csv_df)):
d = abs(r - int(csv_df.loc[i, "R"])) + abs(g - int(csv_df.loc[i, "G"]))+ abs(b - int(csv_df.loc[i, "B"]))
if d <= min_diff:
min_diff = d
color[0] = csv_df.loc[i,"color_name"]
color[1] = csv_df.loc[i,"color_Chi"]
color[2] = str(int(csv_df.loc[i, "R"]))
color[3] = str(int(csv_df.loc[i, "G"]))
color[4] = str(int(csv_df.loc[i, "B"]))
color[5] = csv_df.loc[i, "hex"]
return color
class MyCapture(object):
# 处理全屏截图
def __init__(self, png,root,csv_df):
# 获取屏幕尺寸
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
# 创建顶级组件容器,与屏幕尺寸一样大
self.top = tkinter.Toplevel(root, width=screenWidth, height=screenHeight)
# 不显示最大化、最小化按钮
self.top.overrideredirect(True)
# create a new PhotoImage object
self.image = tkinter.PhotoImage(file=png)
# 创建画布
self.canvas = tkinter.Canvas(self.top,bg='white', width=screenWidth, height=screenHeight)
# 显示全屏截图
self.canvas.create_image(screenWidth//2, screenHeight//2, anchor = tkinter.CENTER, image=self.image)
# 获取鼠标左键抬起的位置,取色
def onLeftButtonUp(event):
im = Image.open(png)
# retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates
color = im.getpixel((event.x, event.y))
temp = [str(item) for item in color]
RGB = "取点的RGB数值:" + ", ".join(temp) + "\n\n"
R,G,B = color
color = get_color_name(R,G,B,csv_df)
color_RGB = "RGB数值:" + ", ".join(color[2:5]) + "\n"
color_hex = "十六进制值:" + color[5] + "\n"
color_Eng = "英文名称:" + color[0] + "\n"
color_Chi = "中文名称:" + color[1] + "\n\n"
msg = "中文名称已复制到剪切板!"
tkinter.messagebox.showinfo('结果展示', RGB + color_RGB + color_hex + color_Eng + color_Chi + msg)
pyperclip.copy(color[1])
# 关闭Toplevel窗口对象
self.top.destroy()
self.canvas.bind('<ButtonRelease-1>', onLeftButtonUp)
self.canvas.pack(fill=tkinter.BOTH, expand=True)
def buttonCaptureClick(root,buttonCapture,csv_df):
# 截图
# 最小化主窗口
root.state('icon')
sleep(0.2)
# 获取临时文件名
filename = uuid.uuid4().hex + ".png"
# 拍摄屏幕全屏,Windows上以RGB图像的形式返回。
im = ImageGrab.grab()
im.save(filename)
im.close()
# 显示全屏幕截图
w = MyCapture(filename,root,csv_df)
# wait_window seems to not return until the given widget passed as parameter is not destroyed.
buttonCapture.wait_window(w.top)
# 截图结束,恢复主窗口,并删除临时的全屏幕截图文件
root.state('normal')
os.remove(filename)
def main():
# 获取颜色数据表
index = ["color", "color_name","hex", "color_Chi","R", "G", "B"]
csv_df = pd.read_csv('colors.csv', names=index, header=None, encoding='chinese')
# 窗口
root = tkinter.Tk()
root.title("颜色识别器v2")
# 窗口宽250,高60; 左上角坐标:(400,300)
root.geometry('250x60+400+300')
#不可更改窗口大小
# root.resizable(False, False)
buttonCapture = tkinter.Button(root, text='取色',width=6,command=lambda:buttonCaptureClick(root,buttonCapture,csv_df))
buttonExit = tkinter.Button(root, text='退出',width=6,command=root.destroy)
buttonCapture.grid(row=0,column=0,padx = 40,pady =10)
buttonExit.grid(row=0,column=1,padx = 40,pady =10)
#启动消息主循环
root.mainloop()
if __name__ == '__main__':
main()
效果演示:
http://mpvideo.qpic.cn/0bc3taaakaaazyaaitishjrfbggdawmaabia.f10002.mp4?dis_k=80bd5645282a6971b746f16b2da516eb&dis_t=1663653830&vid=wxv_2277589062624641024&format_id=10002&support_redirect=0&mmversion=false
参考资料:
[1] Python实现屏幕取色器功能
[2] color-names(https://github.com/codebrainz/color-names/blob/master/output/colors.csv)
[3] 基于Python的颜色识别器(https://zhuanlan.zhihu.com/p/342372391)
[4] Python PIL ImageGrab.grab()用法及代码示例(https://vimsky.com/examples/usage/pyhton-pil-imagegrab-grab-method.html)
[5] 如何让tkinter窗口最小化(https://www.pynote.net/archives/1352)
[6] What does the"wait_window" method do(https://stackoverflow.com/questions/28388346/what-does-thewait-window-method-do)
[7] Tkinter PhotoImage(https://www.pythontutorial.net/tkinter/tkinter-photoimage/)
[8] Canvas image objects(https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/create_image.html)
[9] Python PIL | getpixel() Method(https://www.geeksforgeeks.org/python-pil-getpixel-method/)
[10] Python GUI设计:tkinter菜鸟编程(https://item.jd.com/12667860.html)
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有