步骤1 想法起源
在设计开发炫彩灯环控制器的过程中,对行空板的GUI函数,进行了较多的了解。
第一版的炫彩灯环控制器,选了16种颜色,然后生成色块,用于点击取色:
在这种情况下,每个色块,都使用 GUI.fill_round_rect() 画出来,并设置好onclick回调,这样子点击对应的色块的时候,就能知道点击的是谁,从而取的提前定以后的对应颜色。
后来,又进一步想,能不能通过一张色卡图片,点击不同图片的区域,通过点击位置的坐标,从而获得对应的颜色呢?
经过李亮大佬的指点,最终实现如下的屏幕取色卡功能:
步骤2 预备知识1:行空板的GUI处理
行空板的Python,提供了专用的unihiker库,其中有GUI处理的类。
从GUI处理类的调用方法中,有一个显示图像的方法,具体如下:
这个地方的cn书image,不仅可以直接传入一个图片文件的路径,还可以传入一个PIL.Image对象,具体代码如官方示例:
而通过PIL.Image对象,就可以很方便的打开一张图片,进行各种图形处理操作,包括取指定位置的颜色。
步骤3 预备知识2
上一步说了,可以通过PIL.Image对象,取指定位置的颜色,那具体是如何进行的呢?
其实很简单,代码如下:
img = Image.open("imgs/color_chart.png")
color = img.getpixel(100, 100)
上述代码,就表示先打开imgs/color_chart.png图片,然后取得相对于图片左上角为原点的坐标(100,100)位置的像素的颜色。
但是有一点需要注意的是,上面的坐标(100,100),是相对于图片左上角的,不是相对于屏幕左上角的。
但我们在触摸屏幕时,通过触摸所获取的坐标,是屏幕坐标。因此,需要进行一些处理,将这两者相对应。
最简单的一个办法,就是让图片的宽度,与屏幕的宽度一样,并让图片显示到以屏幕左上角为原点的坐标(0,0)上,这样子,只要是点击了屏幕上图片的任一位置,其取得的屏幕坐标,都直接对应到了图片坐标上了。
因为在屏幕顶部,还需要显示其他的内容,所以可以将图片显示在屏幕上的坐标,往下移一下,例如显示到(0,30)的位置,那么通过屏幕触摸取得的坐标(x,y),对应到图片就是(x, y-30)。
要让图片的宽度,与屏幕的宽度一样,可以有两种办法。一种是图片的实际宽度,就等于屏幕的宽度,一种是通过PIL.Image来讲图片的宽度,调整大小,使得宽度等于屏幕的宽度。前者通过工具软件进行处理,后者直接在Python中编码即可。
通过PIL.Image调整图片宽度的方式如下:
img = Image.open("imgs/color_chart.png")
img2 = img.resize((240,240))
img.close()
需要注意的是,Image.resize()会生成一个新的图片对象,而原有的不变。
步骤4 预备知识3:屏幕触摸坐标位置
在行空板的GUI处理类中,提供了两类获取屏幕点击事件的方式:
# 控件的onclick触发
info_text = gui.draw_text(x=120, y=320, text='你好',origin='bottom' ,onclick=info_text_on_click)
# 鼠标的移动触发
def mouse_move(x, y):
info_text.config(text="坐标:x={},y={}".format(x, y))
print(x,y)
gui.on_mouse_move(mouse_move)
onclick触发调用的时候,只能知道有一次屏幕点击控件发生了,可以知道是在哪个控件上触发的,但是,并不知道具体点击的坐标位置。
on_mouse_move就可以。当在屏幕上触摸移动的时候,类似于在屏幕上移动鼠标,会实时的调用on_mouse_move对应的回调函数,并将当前坐标位置(x,y)做为参数传入。
然后,在回调函数中,就可以使用传入的x, y进行进一步处理了。
步骤5 逻辑设计
步骤6 代码编写
# -*- coding: UTF-8 -*-
import sys
import time
from unihiker import GUI
from PIL import Image
# 屏幕鼠标移动回调
def mouse_move(x, y):
global move_time, mouse_status, color_chart_image, mouse_color
# 显示坐标值
pos_text.config(x=0,text="坐标:({},{})".format(x, y))
# 判断是否在色卡图片上移动
if y>=30 and y < 30+240:
# 在色卡图片中取色
mouse_color = color_chart_image.getpixel((x, y-30))
else:
# 超出则使用(0,0,0)
mouse_color = (0,0,0)
# 显示颜色之
color_text.config(x=100,text="颜色:({},{},{})".format(mouse_color[0],mouse_color[1],mouse_color[2]))
# 更新预览图片颜色
color_img.config(color=mouse_color)
# 更新当前移动时间
move_time = time.time()
# 设置移动状态
mouse_status = 1
# 打开色卡图片
color_chart_image_default = Image.open("imgs/color_chart.png")
# 调整色卡图片大小
color_chart_image = color_chart_image_default.resize((240,240)).convert('RGB')
# 关闭默认打开的色卡图片
color_chart_image_default.close()
# 初始化屏幕
gui = GUI()
gui.clear()
# 初始化屏幕标识文本
gui.draw_text(x=50, y=0, text="WS2812B色卡", font_size=13)
gui.draw_image(x=0,y=30,w=240,h=240,image=color_chart_image)
pos_text = gui.draw_text(x=40, y=300, text='鼠标坐标', font_size=10)
color_text = gui.draw_text(x=150, y=300, text='颜色', font_size=10)
# 初始化颜色预览色块
color_img = gui.fill_round_rect(x=224, y=304, w=14, h=14, r=2, color=(255,255,255))
# 设定中间量初始值
move_time = 0
mouse_status = 0
mouse_color = (0,0,0)
# 屏幕鼠标移动回调绑定
gui.on_mouse_move(mouse_move)
# 循环
while True:
time.sleep(1)
步骤7 实际效果
花生编程2023.01.23
赞
花生编程2023.01.23
厉害
三春牛-创客2023.01.04
不错
三春牛-创客2023.01.04
厉害厉害
好奇号2022.12.30
............
Nd0TAy8yduIE2022.11.21
具体能干嘛呢
糖醋花生2022.12.09
好玩呀