文档连接:https://doc.itprojects.cn/0006.zhishi.esp32/02.doc/index.html#/12.240x240gif
1、制作要显示的动图(动图显示时间不要过长)。
2、将动图转换为多张静态图片,这里使用 Python 代码去做。
from PIL import Image
from PIL import ImageSequence
img = Image.open('C:\\Users\\Administrator\\Desktop\\123.gif')
i = 0
for frame in ImageSequence.Iterator(img):
frame.save("frame%d.png" % i)
i += 1
3、调整图片大小
from PIL import Image # python3安装pillow库
import os.path
import glob
def convertSize(jpgfile, outdir, width=125, height=225): # 图片的大小256*256
img = Image.open(jpgfile)
try:
new_img = img.resize((width, height), Image.BILINEAR)
if new_img.mode == 'P':
new_img = new_img.convert("RGB")
if new_img.mode == 'RGBA':
new_img = new_img.convert("RGB")
new_img.save(os.path.join(outdir, os.path.basename(jpgfile)))
except Exception as e:
print(e)
for jpgfile in glob.glob("*.png"): # 修改该文件夹下的图片
convertSize(jpgfile, "./") # 另存为的文件夹路径
4、将图片转换为.dat文件
import struct
import numpy as np
from PIL import Image
def color565(r, g, b):
return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3
def main():
for i in range(1, 16): # 16张图片循环播放
img = Image.open("frame{}.png".format(i))
print(i, img.format, img.size, img.mode)
img_data = np.array(img) # 225行125列有3个 225x125x3
with open("./frame{}.dat".format(i), "wb") as f:
for line in img_data:
for dot in line:
f.write(struct.pack("H", color565(*dot))[::-1])
if __name__ == '__main__':
main()
5、就是要把转换好的 .dat 文件传给 ESP32,这是使用无线局域网的传输方式。首先在 ESP32 端运行接收代码(连接到 WiFi 后把自己的 ip 地址告诉给电脑),然后在电脑端运行发送代码。
接收端代码:
import time
import network
import machine
import socket
def do_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ChinaNet-SAD8JJ', '13179734613')
i = 1
while not wlan.isconnected():
print("正在链接...{}".format(i))
i += 1
time.sleep(1)
print('network config:', wlan.ifconfig())
# 0. 连接wifi
do_connect()
# 1. 创建 TCP 套接字
server_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定本地信息
server_s.bind(("", 8080))
# 3. 设置为被动的
server_s.listen(128)
print("等待对方链接...")
# 4. 等待客户端链接
new_s, client_info = server_s.accept()
print("等待对方发送图片数据...")
# 3. 创建文件,接收数据
for i in range(1, 16): # 15张图片循环播放
with open("img{}.dat".format(i), "wb") as f:
for j in range(225):
# 3.1 接收数据
data = new_s.recv(250) # 125*2=250 一行有125个点, 每个点有两个字节
# 3.2 写到文件
f.write(data)
# print("接收第%d行" % (i+1))
print("img{}--接收完毕".format(i))
# 7. 关闭套接字
new_s.close()
server_s.close()
发送端代码:
import struct
import numpy as np
from PIL import Image
def color565(r, g, b):
return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3
def main():
for i in range(1, 16): # 16张图片循环播放
img = Image.open("frame{}.png".format(i))
print(i, img.format, img.size, img.mode)
img_data = np.array(img) # 225行125列有3个 225x125x3
with open("./frame{}.dat".format(i), "wb") as f:
for line in img_data:
for dot in line:
f.write(struct.pack("H", color565(*dot))[::-1])
if __name__ == '__main__':
main()
6、显示动图代码,是在上一节显示静态图片的驱动上改的。
import random
from machine import Pin, SPI
import st7789
import st7789py
# 解决第1次启动时,不亮的问题
st7789.ST7789(SPI(2, 80000000), dc=Pin(2), cs=Pin(5), rst=Pin(15))
# 创建显示屏对象
tft = st7789py.ST7789(SPI(2, 10000000), 135, 240, reset=Pin(15), dc=Pin(2), cs=Pin(5), rotation=0)
# 屏幕显示蓝色
tft.fill(st7789py.color565(0, 0, 0))#RGB
# 因为用到了15张图片,所以这里创建15个文件对象
f_list = [open("img{}.dat".format(i), "rb") for i in range(1, 16)]
def show_img():
for f in f_list:
f.seek(0) # 让文件指针指向0, 即从img1开始播放
for row in range(0, 225, 25): # 从0行开始,一共有225行,每次读取22行有问题(尽量取能整除的数)
buffer = f.read(250*25)
tft.show_img(0, row, 124, row+25, buffer) #起点坐标(0, row),终点坐标(124, row)
while True:
show_img()
每次读取的行数阅读,播放的速度就越快,既不能每次读取的行数太多(48行没问题),否则会申请内存错误。也不能一行一行的读取,否则刷新太慢,有过于明显地刷新页面的过程,显示效果不佳。尽量每次读取是行数的整数倍 (尽量取能整除的数),避免还剩半行没读完的情况,比如这里读取 22 行就有问题。