当前位置:首页 > Python教程 > 正文内容

自制Python小工具将HEIC转PNG

Codekpy3个月前 (01-22)Python教程290

CodeKpy的博客-使用 HEIC 转换为 PNG 工具

文末附有全部代码

本文将教你如何使用 Python 和 Tkinter 创建一个 HEIC (High Efficiency Image Coding) 到 PNG 格式的转换器。这个应用不仅支持批量转换 HEIC 文件,还支持通过双击文件来进行单独转换。跟随这个教程,你将学会如何使用 Tkinter 构建一个简单的图形用户界面、选择文件、展示文件列表,并通过后台线程来处理转换任务。

前提条件

1.Python 3.x
2.heic2png Python 库(用于 HEIC 转 PNG 格式转换)
3.Tkinter(用于构建图形用户界面)

安装依赖

首先,需要安装 heic2png 库。运行以下命令来安装:
pip install heic2png

Tkinter 通常会随 Python 一起安装。如果没有安装,可以参考相关文档进行安装。

步骤 1:创建应用界面

4.导入必要的库

import tkinter as tk
from tkinter import filedialog, messagebox
from heic2png import HEIC2PNG
import os
import threading

5.创建应用类

首先,创建一个 HEICConverterApp 类,并设置窗口标题、大小、文件路径和文件列表。

class HEICConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("HEIC to PNG 转换器")
        self.root.geometry("600x500")
        self.filepath = ""
        self.files = []

6.设置菜单栏和菜单选项

添加菜单项让用户可以选择文件夹或单个文件。

        menubar = tk.Menu(root)
        root.config(menu=menubar)

        file_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="选择文件夹", command=self.select_folder)
        file_menu.add_command(label="选择文件", command=self.select_file)

7.创建文件列表框

在窗口中添加一个列表框,用来显示选中的 HEIC 文件。

        self.file_listbox = tk.Listbox(root, selectmode=tk.MULTIPLE, width=80, height=20)
        self.file_listbox.pack(pady=20)

8.创建按钮

添加“批量转换”和“转换”按钮来触发转换操作。

        button_frame = tk.Frame(root)
        button_frame.pack(pady=10)

        batch_convert_btn = tk.Button(button_frame, text="批量转换", command=self.batch_convert)
        batch_convert_btn.pack(side=tk.LEFT, padx=5)

        convert_btn = tk.Button(button_frame, text="转换", command=self.convert)
        convert_btn.pack(side=tk.LEFT, padx=5)

步骤 2:实现文件选择和显示功能

9.选择文件夹

用户选择文件夹后,程序会列出所有 HEIC 文件。

    def select_folder(self):
        self.filepath = filedialog.askdirectory()
        if not self.filepath:
            return
        self.files = [f for f in os.listdir(self.filepath) if f.lower().endswith(".heic")]
        self.update_file_listbox()

10.选择单个文件

允许用户选择单个 HEIC 文件,并更新文件列表框。

def select_file(self):
    file = filedialog.askopenfilename(filetypes=[("HEIC files", "*.HEIC")])
    if file:
        self.files = [os.path.basename(file)]
        self.update_file_listbox()

11.更新文件列表框

更新列表框,显示当前选中的文件。

    def update_file_listbox(self):
        self.file_listbox.delete(0, tk.END)
        for file in self.files:
            self.file_listbox.insert(tk.END, file)

步骤 3:实现转换功能

12.批量转换功能

当用户选择文件夹后,点击“批量转换”按钮会启动一个新线程,处理所有 HEIC 文件的转换。

    def batch_convert(self):
        if not self.filepath:
            messagebox.showerror("错误", "请先选择一个文件夹。")
            return
        thread = threading.Thread(target=self._batch_convert)
        thread.start()

    def _batch_convert(self):
        for file in self.files:
            fullpath = os.path.join(self.filepath, file)
            heic_img = HEIC2PNG(fullpath)
            png_path = fullpath.lower().replace(".heic", ".png")
            heic_img.save(png_path)
        self.root.after(0, lambda: messagebox.showinfo("成功", "转换已完成。"))

13.单个文件转换

选中文件后,点击“转换”按钮进行单个文件转换。

    def convert(self):
        selected_indices = self.file_listbox.curselection()
        if not selected_indices:
            messagebox.showerror("错误", "请从列表中选择一个文件。")
            return
        files_to_convert = [self.files[i] for i in selected_indices]

        thread = threading.Thread(target=self._convert_files, args=(files_to_convert,))
        thread.start()

    def _convert_files(self, files_to_convert):
        for file in files_to_convert:
            fullpath = os.path.join(self.filepath, file)
            heic_img = HEIC2PNG(fullpath)
            heic_img.save(fullpath.replace(".heic", '.png'))
        self.root.after(0, lambda: messagebox.showinfo("成功", "选择的文件已被转换。"))

14.双击文件进行转换

实现双击列表中的文件时自动触发转换。

    def on_item_double_click(self, event):
        selected_indices = self.file_listbox.curselection()
        if not selected_indices:
            return
        file = self.files[selected_indices[0]]
        if messagebox.askyesno("确认", f"是否转换 {file}?"):
            self.convert_file(os.path.join(self.filepath, file))

    def convert_file(self, fullpath):
        try:
            heic_img = HEIC2PNG(fullpath)
            png_path = fullpath.lower().replace(".heic", ".png")
            heic_img.save(png_path)
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("转换错误", f"{fullpath}: {str(e)}"))

步骤 4:运行应用

最后,初始化应用并启动 Tkinter 的主循环:

if __name__ == "__main__":
    root = tk.Tk()
    app = HEICConverterApp(root)
    root.mainloop()

总结

通过本教程,我们已经创建一个简单的 HEIC 到 PNG 转换工具,支持批量转换、单文件转换、以及通过双击文件来触发转换。你可以根据自己的需求扩展更多功能,比如支持其他格式的转换或自定义转换设置等。

全部代码

import tkinter as tk
from tkinter import filedialog, messagebox
from heic2png import HEIC2PNG
import os
import threading

class HEICConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("HEIC to PNG 转换器")
        self.root.geometry("600x500")

        self.filepath = ""
        self.files = []

        # 创建菜单栏
        menubar = tk.Menu(root)
        root.config(menu=menubar)

        # 创建文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="选择文件夹", command=self.select_folder)
        file_menu.add_command(label="选择文件", command=self.select_file)

        # 创建一个列表框来显示 HEIC 文件
        self.file_listbox = tk.Listbox(root, selectmode=tk.MULTIPLE, width=80, height=20)
        self.file_listbox.pack(pady=20)

        # 绑定双击事件
        self.file_listbox.bind("<Double-1>", self.on_item_double_click)

        # 创建按钮
        button_frame = tk.Frame(root)
        button_frame.pack(pady=10)

        batch_convert_btn = tk.Button(button_frame, text="批量转换", command=self.batch_convert)
        batch_convert_btn.pack(side=tk.LEFT, padx=5)

        convert_btn = tk.Button(button_frame, text="转换", command=self.convert)
        convert_btn.pack(side=tk.LEFT, padx=5)

    def select_folder(self):
        self.filepath = filedialog.askdirectory()
        if not self.filepath:
            return

        self.files = [f for f in os.listdir(self.filepath) if f.lower().endswith(".heic")]
        self.update_file_listbox()

    def select_file(self):
        file = filedialog.askopenfilename(filetypes=[("HEIC files", "*.HEIC")])
        if file:
            self.files = [os.path.basename(file)]
            self.update_file_listbox()

    def update_file_listbox(self):
        self.file_listbox.delete(0, tk.END)
        for file in self.files:
            self.file_listbox.insert(tk.END, file)

    def batch_convert(self):
        if not self.filepath:
            messagebox.showerror("错误", "请先选择一个文件夹。")
            return

        thread = threading.Thread(target=self._batch_convert)
        thread.start()

    def _batch_convert(self):
        for file in self.files:
            fullpath = os.path.join(self.filepath, file)
            heic_img = HEIC2PNG(fullpath)
            if "heic" in fullpath.lower():
                png_path = fullpath.lower().replace(".heic", ".png")
            else:
                png_path = fullpath.lower().replace(".HEIC", ".png")
            heic_img.save(png_path)

        self.root.after(0, lambda: messagebox.showinfo("成功", "转换已完成。"))

    def convert(self):
        selected_indices = self.file_listbox.curselection()
        if not selected_indices:
            messagebox.showerror("错误", "请从列表中选择一个文件。")
            return

        files_to_convert = [self.files[i] for i in selected_indices]

        thread = threading.Thread(target=self._convert_files, args=(files_to_convert,))
        thread.start()

    def _convert_files(self, files_to_convert):
        for file in files_to_convert:
            fullpath = os.path.join(self.filepath, file)
            heic_img = HEIC2PNG(fullpath)
            heic_img.save(fullpath.replace(".heic", '.png'))

        self.root.after(0, lambda: messagebox.showinfo("成功", "选择的文件已被转换。"))

    def on_item_double_click(self, event):
        selected_indices = self.file_listbox.curselection()
        if not selected_indices:
            return

        file = self.files[selected_indices[0]]
        if messagebox.askyesno("确认", f"是否转换 {file}?"):
            self.convert_single(file)

    def convert_file(self, fullpath):
        try:
            heic_img = HEIC2PNG(fullpath)
            if "heic" in fullpath.lower():
                png_path = fullpath.lower().replace(".heic", ".png")
            else:
                png_path = fullpath.lower().replace(".HEIC", ".png")
            heic_img.save(png_path)
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("转换错误", f"{fullpath}: {str(e)}"))


if __name__ == "__main__":
    root = tk.Tk()
    app = HEICConverterApp(root)
    root.mainloop()


分享给朋友:

相关文章

Python3.8.8高速下载

蓝奏云地址:https://codekpy.lanzn.com/iCmTd2mjj81c密码:cp4y...

使用Python脚本激活虚拟环境并获取pip列表

教程:使用Python脚本激活虚拟环境并获取pip列表1. 准备工作在开始之前,请确保您的计算机已安装以下软件:Pythonpip(Python包管理器)2. 创建虚拟环境首先,您需要创建一个虚拟环境...