代码拉取完成,页面将自动刷新
同步操作将从 YYM/oledDisplayGif 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
import os
from pathlib import WindowsPath
import tkinter
from tkinter import *
from tkinter.filedialog import askdirectory,askopenfilename
import tkinter.messagebox
from PIL import Image,ImageSequence
import threading
Adafruit_SSD1306_1 ='''
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
'''
Adafruit_SSD1306_2 ='''
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
}
int xx = 0;
int yy = 0;
int tt = 40;
void loop() {
'''
u8g2_1 = '''
#include <Arduino.h>
#include <U8g2lib.h>
'''
u8g2_2 ='''
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
/** 根据你的板子(Arduino,ESP8266,ESP32)取消注释哪一行 **/
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 22, /* data=*/ 21); // ESP32 IO22:SCL IO21:SDA
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // arduino A4:SDA A5:SCL
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // ESP8266(NodeMCU) D1:SCL D2:SDA
int xx = 0;
int yy = 0;
int tt = 40;
void setup(void) {
u8g2.begin();
u8g2.setFont(u8g2_font_ncenB14_tr);
}
void loop(void) {
'''
findex = 0
codeIndex = 0
eachFramesTime = []
def saveFps(PIL_Image_object):
"""
提取并保存GIF图片的每一帧,和每帧延时时间
将会在当前目录下创建一个 FUCK 文件夹 保存每一帧图片,默认为PNG格式
"""
if not os.path.exists(os.getcwd()+'\\fuck'):
os.mkdir(os.getcwd()+'\\fuck')
os.chdir(os.getcwd())
print("切换到%s"%( os.getcwd() ) )
PIL_Image_object.seek(0)
frames = duration = 0
imgiter = ImageSequence.Iterator(PIL_Image_object) # GIF图片流的迭代器
for frame in imgiter: # 遍历图片流的每一帧
try:
frames += 1
duration = PIL_Image_object.info['duration'] #获取当前帧的持续时间
eachFramesTime.append(duration) #将当前帧时间保存到列表
#print("第%d帧时间%d ms"%(frames,duration))
PIL_Image_object.seek(PIL_Image_object.tell() + 1)
frame.save(os.getcwd()+'\\fuck'+"\\"+str(frames)+'.png') #保存当前帧
duration = 0
except EOFError: # 当没有下一帧时会引发此错误
pass
#tkinter.messagebox.showwarning(title='OK',message='转换完成')
def remove_transparency(im, bg_colour=(255, 255, 255)):
'''
@function:删除PNG图片的透明度
@parameter: im - Image object
bg_colour - BackgroundColor
'''
# 仅当图像具有透明度时进行处理
if im.mode in ('RGBA', 'LA') or (im.mode == 'P' and 'transparency' in im.info):
# 需要转换为RGBA如果LA格式由于PIL的一个bug
alpha = im.convert('RGBA').split()[-1]
# 创建一个新的背景图像的马特色.
# 必须是RGBA,因为粘贴要求两个图像有相同的格式
bg = Image.new("RGBA", im.size, bg_colour + (255,))
bg.paste(im, mask=alpha)
return bg
else:
return im
def ma():
'''
转为BMP格式
'''
print('转为bmp格式')
print(os.listdir(os.getcwd()))
for i in (os.listdir(os.getcwd())):
if i.lower().split('.')[-1] == 'png' or i.lower().split('.')[-1] == 'jpg': #判断图片格式是否为 png 或 jpg
imgName = i.lower().split('.')[0] #获取文件名
#i = oldpath + '\\'+i
if i.lower().split('.')[-1] == 'jpg':
img = Image.open(i) #打开图片
img = remove_transparency(img) #透明度处理
img.save(imgName+'.bmp','bmp')
if i.lower().split('.')[-1] == 'png':
img = Image.open(i).convert("1") #打开图片
img.save(imgName+'.bmp','bmp')
for i in (os.listdir(os.getcwd())):
if i.lower().split('.')[-1] == 'png' or i.lower().split('.')[-1] == 'jpg': #判断图片格式是否为 png 或 jpg
os.remove(i) # 删除 后缀为 jpg 或 png 的图片
#tkinter.messagebox.showwarning(title='OK',message='转换完成')
print(" 转为BMP格式转换完成!")
def resizeImg():
'''
重置大小
'''
print("重置图片大小")
os.chdir(os.getcwd()+"\\fuck")
new_size = (48,48)
#print(os.listdir(newpath))
file = os.listdir(os.getcwd()) # 获取路径下的所有文件
print(file)
file.sort(key= lambda x:int(x[:-4])) # 按照文件名 排序
index1 = 0
for each in file:
index1 = index1 + 1
image = Image.open(each)
new_image = image.resize(new_size)
new_image.save(str(index1) + '.png','png')
#os.remove(each)
#tkinter.messagebox.showwarning(title='ok',message='重置完成')
print("重置大小完成")
def bmp2hex():
'''
图片取模
'''
print("你选则的是%s"%(variable.get()))
os.chdir(os.getcwd())
print("图片取模")
print(os.getcwd())
print("你选则的是%s"%(variable.get()))
filename = entry.get()
outPutFile = filename + ".h"
global codeIndex
codeIndex = 0
file = os.listdir(os.getcwd()) # 获取路径下的所有文件
print(file)
file.sort(key= lambda x:int(x[:-4])) # 按照文件名 排序
print(os.listdir(os.getcwd()))
for i in (file):
codeIndex = codeIndex+1
print("正在处理>>>> %d"%(codeIndex))
img = Image.open(i)
(width,height) = img.size #获取图片的宽 高信息
list1 = []
list2 = []
for w in range(height):
for h in range(width):
pixel=img.getpixel((h,w)) # 获取图片的像素点
if variable.get() == "u8g2": # 01反转
if pixel == 255:
pixel = 0
else:
pixel = 1
list1.append(pixel) # 当前像素值添加到列表里
else:
if pixel == 255:
pixel = 0
else:
pixel = 1
list1.append(pixel) # 当前像素值添加到列表里
list2.append(list1.copy())
list1.clear()
while len(list2[0])%8 != 0: # 判断是否为8的倍数,不足补0
for i in range(len(list2)): # 循环每一行
list2[i].append(0) # 末尾补0
lenth = len(list2[0])//8
#print(lenth)
j=0
k=0
l1 = []
num = 0
res = ''
column = 0
f = open(outPutFile,'a+')
f.write('\nconst unsigned char PROGMEM '+ filename +str(codeIndex)+'[] = {\n')
f.close()
for m in range(len(list2)): #行循环
for i in range(lenth): #列循环
j = j+7
l1 = list2[m][k:j+1] # 提取8位
if variable.get()=="u8g2": # 是否字节倒叙(U8G2需要此选项)
l1.reverse() # 列表翻转(字节倒叙)
for q in range(len(l1)):
num = num | l1[q]<<7-q # 合并8位单独数字
res = '0x' + str(hex(num))[2:].zfill(2)+"," # 格式化为0x00样式
f = open(outPutFile,'a+')
f.write(res)
f.close()
column = column + 1
if column>=12: # 每行个数控制,达到位数时换行
f = open(outPutFile,'a+')
f.write('\n')
f.close()
column = 0
num = 0
k = j+1
j = j+1
findex = codeIndex
j=0
k=0
l1 = []
f = open(outPutFile,'a+')
f.write('};')
f.close()
#tkinter.messagebox.showwarning(title='ok',message='保存完成')
def selectGifFile():
global gif_file
gif_file = askopenfilename(title="选择GIF图片",filetypes=[("GIF Image",'*.gif')])
os.chdir(os.path.dirname(gif_file))
print(gif_file)
def generateArduinoCode():
os.chdir(os.getcwd())
arryname = entry.get()
print('findex',codeIndex)
if variable.get()=="Adafruit_SSD1306": # Adafruit_SSD1306 code
outPutFile = "Adafruit_SSD1306code.txt"
with open(outPutFile,'a+') as f:
f.write(Adafruit_SSD1306_1+'\n#include "'+arryname+'.h"'+Adafruit_SSD1306_2) # 写入相关头文件
for i in range(1,codeIndex+1):
with open(outPutFile,'a+') as f:
f.write('display.clearDisplay();\ndisplay.drawBitmap(xx, yy,'+ arryname +str(i)+',48,48, 1);\ndisplay.display();\ndelay('+str(eachFramesTime[i])+');\n\n')
with open(outPutFile,'a+') as f:
f.write("}")
tkinter.messagebox.showwarning(title='ok',message='操作完成')
else: # u8g2 code
outPutFile = "u8g2code.txt"
with open(outPutFile,'a+') as f:
f.write(u8g2_1+'\n#include "'+arryname+'.h"'+u8g2_2)
for i in range(1,codeIndex+1):
with open(outPutFile,'a+') as f:
f.write(' u8g2.firstPage();\n do {\n u8g2.drawXBMP(xx,yy, 48, 48,'+ arryname +str(i)+');\n} while ( u8g2.nextPage() );\n delay('+str(eachFramesTime[i])+');\n\n')
with open(outPutFile,'a+') as f:
f.write("}")
tkinter.messagebox.showwarning(title='ok',message='操作完成')
def beginSpilt():
img = Image.open(gif_file) # 打开选择的GIF
saveFps(img) # 提取并保存GIF的每一帧
resizeImg() # 重置图片大小(改为48X48)
ma(); # 转为BMP格式
bmp2hex()# 图片取模,保存数组文件
generateArduinoCode(); # 生成 Arduino 代码
def splitGif():
'''
开始转换
'''
tkinter.messagebox.showwarning(title='开始',message='需要一小会儿时间...请稍后,点击确定开始')
splitThread = threading.Thread(target=beginSpilt)
splitThread.setDaemon(True)
splitThread.start()
windows = Tk()
windows.title("OLED动图生成,作者:YYM")
windows.geometry('300x300')
windows.resizable(0,0)
text = "分割GIF,转BMP格式,生成 Arduino 代码 \n目前只支持0.96OLED ssd1306芯片 IIC"
text2 = "选择你使用的库文件"
L1 = Label(windows,text=text)
L1.pack()
L2 = Label(windows,text=text2,fg="red")
L2.pack()
variable = StringVar()
variable.set("Adafruit_SSD1306")
w = OptionMenu(windows, variable, "Adafruit_SSD1306", "u8g2") # 创建以及下拉框,用于选择头文件
w.pack()
bb1 = Button(windows,text="选择GIF图片",command=selectGifFile)
bb1.pack()
text3= "在下方输入框写入数组名,\n生成的数组文件也会为此名,\n注意命方式和C语言一致"
L3 = Label(windows,text=text3,fg="red")
L3.pack()
entry = Entry(windows)
entry.pack()
entry.insert(0,"数组名(必填)")
bb2 = Button(windows,text='一键生成Arduino代码',command=splitGif)
bb2.pack()
if __name__=="__main__":
mainloop()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。