电脑端微信用户图片DAT格式解码为图片(TK版)

最近学习TK,想写个小项目。正好那原来发过的这个主题进行改进下。

先上图看个效果:

电脑端微信用户图片DAT格式解码为图片(TK版)_第1张图片

 设计思路如下:

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()

你可能感兴趣的:(Python学习,python,开发语言,微信图片)