最近学习TK,想写个小项目。正好那原来发过的这个主题进行改进下。
先上图看个效果:
设计思路如下:
1.选择微信图片文件夹路径
2.读取文件夹下文件,加载到Treeview里(可以学习到Treeview的使用)
3.选中行时,TK Label中显示图片
难点一:(TK,不支持jpg,所以需要用PIL来处理)
难点二:自然是微信图片转位图片的关键部分
4.加保存图片按钮,可在原路径下生成图片。删除图片按钮,可以删除不需要的dat文件,减少空间
源代码可生成的exe文件,链接如下:
微信图片DAT格式解码为图片
完整代码如下,未做整理,仅供学习:
#!/usr/bin/env python
# Author:Veray Zhou
import tkinter as tk
from tkinter.filedialog import *
from tkinter.ttk import *
import os
from PIL import Image, ImageTk
from io import BytesIO
window = tk.Tk()
window.title('电脑端微信用户图片DAT格式解码为图片')
window.geometry('450x750')
files = []
dir_path = ''
newfile_path = ''
def showFiles(dir_path):
inFiles = os.listdir(dir_path)
i = 1
files.clear()
for file in inFiles:
# 获取文件类型
filetype = os.path.splitext(file)[1]
if filetype == '.dat':
# 获取文件大小
filesize = os.path.getsize(os.path.join(dir_path, file))
#序号 文件名 文件大小
files.append((i, file, '{:.2f}KB'.format(filesize/float(1024))))
i += 1
# print(files)
return files
def select_path():
global dir_path
dir_path = askdirectory()
e.delete(0, 'end')
e.insert(0, dir_path)
delete_all()
if dir_path:
files = showFiles(dir_path)
insert()
def insert():
print(files)
for index, file in enumerate(files):
datagrid.insert('', END, values=file)
print(files)
# 默认选中首行
if files:
datagrid.selection_set(datagrid.get_children()[0])
def delete_all():
items = datagrid.get_children()
for item in items:
datagrid.delete(item)
def select(*args):
print(datagrid.selection())
selectItem = datagrid.item(datagrid.selection())['values']
filename = selectItem[1]
showImage(filename)
def showImage(filename):
createTempPic(dir_path, filename)
def createTempPic(files_dir_path, filename):
filePath = os.path.join(files_dir_path, filename)
f1 = open(filePath, 'rb')
infilebytes = f1.read()
newfile = []
global newfile_path
#print(os.path.join(os.path.dirname(filePath), 'temp.jpg'))
# 判断图片类型JPG,通过异或判定
if (infilebytes[0] ^ 0xFF) == (infilebytes[1] ^ 0xD8):
y1 = infilebytes[0] ^ 0xFF
print('%s,文件是JPG图片,每个字节是根据0x%X异或进行加密' % (filePath, y1))
# # 字节进行异或转换,组合成新的文件
for i in infilebytes:
newbyte = i ^ y1
newfile.append(newbyte)
newfile2 = bytes(newfile)
# 显示图片
show(newfile2)
# 判断图片类型PNG,通过异或判定
elif (infilebytes[0] ^ 0x89) == (infilebytes[1] ^ 0x50):
y1 = infilebytes[0] ^ 0x89
print('%s,文件是PNG图片,每个字节是根据0x%X异或进行加密' % (filePath, y1))
for i in infilebytes:
newbyte = i ^ y1
newfile.append(newbyte)
newfile2 = bytes(newfile)
# 显示图片
show(newfile2)
# 判断图片类型GIF,通过异或判定
elif (infilebytes[0] ^ 0x47) == (infilebytes[1] ^ 0x49):
y1 = infilebytes[0] ^ 0x47
print('%s,文件是GIF图片,每个字节是根据0x%X异或进行加密' % (filePath, y1))
for i in infilebytes:
newbyte = i ^ y1
newfile.append(newbyte)
newfile2 = bytes(newfile)
# 显示图片
show(newfile2)
else:
print('%s无法识别的类型!' % filePath)
newfile_path = ''
print('图片已显示!')
# 保存图片
def SavePic(files_dir_path, filename):
filePath = os.path.join(files_dir_path, filename)
f1 = open(filePath, 'rb')
infilebytes = f1.read()
newfile = []
global newfile_path
# 判断图片类型JPG,通过异或判定
if (infilebytes[0] ^ 0xFF) == (infilebytes[1] ^ 0xD8):
y1 = infilebytes[0] ^ 0xFF
print('%s,文件是JPG图片,每个字节是根据0x%X异或进行加密' % (filePath, y1))
# # 字节进行异或转换,组合成新的文件
for i in infilebytes:
newbyte = i ^ y1
newfile.append(newbyte)
newfile2 = bytes(newfile)
# 写入新文件
f2 = open(os.path.join(files_dir_path, filename.lower().replace('.dat', '.jpg')), 'wb')
f2.write(newfile2)
# 判断图片类型PNG,通过异或判定
elif (infilebytes[0] ^ 0x89) == (infilebytes[1] ^ 0x50):
y1 = infilebytes[0] ^ 0x89
print('%s,文件是PNG图片,每个字节是根据0x%X异或进行加密' % (filePath, y1))
for i in infilebytes:
newbyte = i ^ y1
newfile.append(newbyte)
newfile2 = bytes(newfile)
f2 = open(os.path.join(files_dir_path , filename.lower().replace('.dat', '.png')), 'wb')
f2.write(newfile2)
# 判断图片类型GIF,通过异或判定
elif (infilebytes[0] ^ 0x47) == (infilebytes[1] ^ 0x49):
y1 = infilebytes[0] ^ 0x47
print('%s,文件是GIF图片,每个字节是根据0x%X异或进行加密' % (filePath, y1))
for i in infilebytes:
newbyte = i ^ y1
newfile.append(newbyte)
newfile2 = bytes(newfile)
f2 = open(os.path.join(files_dir_path, filename.lower().replace('.dat', '.gif')), 'wb')
f2.write(newfile2)
else:
print('%s无法识别的类型!' % filePath)
print('生成结束')
def show(newfile2):
w_box=423
h_box=310
bytes_stream = BytesIO(newfile2)
img_open = Image.open(bytes_stream)
img_open_resize = img_open.resize((w_box,h_box))
# print(img_open)
img = ImageTk.PhotoImage(image=img_open_resize)
# print(img)
label_show.config(image=img,width=w_box, height=h_box)
label_show.image =img
# def show():
# w_box=422
# h_box=400
# aa = os.path.join(dir_path, 'temp.png')
# print(aa)
# img_open = Image.open(aa)
# img_open_resize = img_open.resize((w_box,h_box))
# print(img_open)
# img = ImageTk.PhotoImage(image=img_open_resize)
# print(img)
# label_show.config(image=img,width=w_box, height=h_box)
# label_show.image =img
e = tk.Entry(window, width=40 )
e.place(x=10, y=20)
var1 = tk.StringVar()
b = tk.Button(window, text='打开文件夹', width=10, command=select_path)
b.place(x=310, y=16)
ybar = Scrollbar(window, orient="vertical")
ybar.place(x=420, y=49, height=329)
datagrid = Treeview(window, height=15, show='headings', column=('no', 'filename', 'filesize'), yscrollcommand=ybar.set)
ybar['command'] = datagrid.yview
datagrid.heading('no', text='序')
datagrid.heading('filename', text='文件名')
datagrid.heading('filesize', text='文件大小')
datagrid.column('no', width=30, minwidth=30, anchor=CENTER)
datagrid.column('filename', width=300, minwidth=280, anchor=CENTER)
datagrid.column('filesize', width=80, minwidth=80, anchor=CENTER)
datagrid.place(x=10, y=50)
datagrid.bind('<>',select)
label_show = tk.Label(window,borderwidth=1,bg='black',width=60,height=18)
label_show.place(x=10,y=380)
def preSel():
preItem = datagrid.prev(datagrid.selection())
if preItem:
datagrid.selection_set(preItem)
else:
print('已经是第一条记录')
preButton = tk.Button(window,text='上一张',width=10, command=preSel)
preButton.place(x=20, y=700)
def nextSel():
nextItem = datagrid.next(datagrid.selection())
if nextItem:
datagrid.selection_set(nextItem)
else:
print('已经是最后一条记录')
nextButton = tk.Button(window,text='下一张',width=10, command=nextSel)
nextButton.place(x=120, y=700)
def save():
selectItem = datagrid.item(datagrid.selection())['values']
filename = selectItem[1]
SavePic(dir_path, filename)
saveButton = tk.Button(window,text='保存图片',width=10,command=save)
saveButton.place(x=220, y=700)
def deletePic(files_dir_path, filename):
filePath = os.path.join(files_dir_path, filename)
print(filePath)
if os.path.isfile(filePath):
os.remove(filePath)
print('删除成功')
else:
print('文件不存在')
def delete():
selectItem = datagrid.item(datagrid.selection())['values']
filename = selectItem[1]
deletePic(dir_path, filename)
datagrid.delete(datagrid.selection())
delButton = tk.Button(window,text='删除图片',width=10, command=delete)
delButton.place(x=320, y=700)
window.mainloop()