最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python自制圖像批量壓縮工具

 更新時(shí)間:2024年04月18日 09:56:16   作者:小鋒學(xué)長(zhǎng)生活大爆炸  
這篇文章主要為大家詳細(xì)介紹了如何使用Python自制一個(gè)圖像批量壓縮工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

可以選擇文件夾或者圖片進(jìn)行壓縮:

可以在這里下載小工具集:

https://github.com/1061700625/small_tools_v2

當(dāng)然,也開源了圖像壓縮工具的代碼:

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from PIL import Image
import os
 
class ImageCompressorApp:
    def __init__(self, master):
        self.master = master
        master.title("圖片批量壓縮工具——小鋒學(xué)長(zhǎng)生活大爆炸[xfxuezhang.cn]")
        window_width = 650
        window_height = 400
        master.geometry(f'{window_width}x{window_height}')
        master.resizable(False, False)
        screen_width = self.master.winfo_screenwidth()
        screen_height = self.master.winfo_screenheight()
        center_x = int(screen_width / 2 - window_width / 2)
        center_y = int(screen_height / 2 - window_height / 2)
        self.master.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
        style = ttk.Style()
        style.theme_use('clam')  # 使用clam主題
 
        # 設(shè)置不同控件的樣式
        style.configure('TButton', background='#E1E1E1', foreground='black', width=20, borderwidth=1)
        style.configure('TEntry', foreground='black', borderwidth=1)
        style.configure('TLabel', foreground='black', background='#E1E1E1')
        style.configure('Horizontal.TProgressbar', background='#5CB85C', thickness=10)
 
        # 容器框架
        top_frame = ttk.Frame(master, padding=10)
        path_frame = ttk.Frame(master, padding=10)
        button_frame = ttk.Frame(master, padding=10)
        slider_frame = ttk.Frame(master, padding=10)
        action_frame = ttk.Frame(master, padding=20)
        estimate_frame = ttk.Frame(master, padding=10)
 
        # 布局框架
        for frame in [top_frame, path_frame, button_frame, slider_frame, action_frame, estimate_frame]:
            frame.pack(fill=tk.X, padx=10, pady=5)
 
        # 單選按鈕設(shè)置
        self.selection_mode = tk.StringVar(value="folder")
        ttk.Radiobutton(top_frame, text="文件夾", variable=self.selection_mode, value="folder", command=self.clear_and_toggle).pack(side=tk.LEFT)
        ttk.Radiobutton(top_frame, text="圖片", variable=self.selection_mode, value="file", command=self.clear_and_toggle).pack(side=tk.LEFT)
 
        # 路徑和后綴輸入框
        self.path_entry = ttk.Entry(path_frame, width=40)
        self.path_entry.pack(side=tk.LEFT, expand=True, fill=tk.X)
        self.suffix_entry = ttk.Entry(path_frame, width=10)
        self.suffix_entry.insert(0, "new")
        self.suffix_entry.pack(side=tk.LEFT)
 
        # 按鈕配置
        self.folder_button = ttk.Button(button_frame, text="選擇文件夾", command=self.browse_folder)
        self.folder_button.pack(side=tk.LEFT, padx=5)
        self.file_button = ttk.Button(button_frame, text="選擇圖片", command=self.browse_file)
        self.file_button.pack(side=tk.LEFT, padx=5)
 
        # 滑塊配置
        ttk.Label(slider_frame, text="壓縮率 (0-100%):").pack(side=tk.LEFT)
        self.quality_slider = ttk.Scale(slider_frame, from_=0, to=100, orient=tk.HORIZONTAL)
        self.quality_slider.pack(side=tk.LEFT, fill=tk.X, expand=True)
        self.quality_entry = ttk.Entry(slider_frame, width=4)
        self.quality_entry.pack(side=tk.LEFT)
        ttk.Label(slider_frame, text="縮放率 (0-100%):").pack(side=tk.LEFT)
        self.resize_slider = ttk.Scale(slider_frame, from_=0, to_=100, orient=tk.HORIZONTAL)
        self.resize_slider.pack(side=tk.LEFT, fill=tk.X, expand=True)
        self.resize_entry = ttk.Entry(slider_frame, width=4)
        self.resize_entry.pack(side=tk.LEFT)
 
        # 壓縮按鈕和進(jìn)度條
        self.compress_button = ttk.Button(action_frame, text="開始?jí)嚎s", command=self.start_compression)
        self.compress_button.pack(side=tk.TOP)
        self.progress = ttk.Progressbar(action_frame, orient=tk.HORIZONTAL, mode="determinate", length=500)
        self.progress.pack(fill=tk.X, expand=True)
 
        # 尺寸估計(jì)標(biāo)簽
        self.size_estimate_label = ttk.Label(estimate_frame, text="估計(jì)壓縮后大小: 未知")
        self.size_estimate_label.pack(side=tk.BOTTOM, pady=(5, 10))
 
        # 初始化狀態(tài)
        self.clear_and_toggle()
        self.update_resize_entry(100)
        self.update_quality_entry(100)
        self.resize_slider.set(100)
        self.quality_slider.set(100)
        
 
    def clear_and_toggle(self):
        self.path_entry.delete(0, tk.END)
        if self.selection_mode.get() == "folder":
            self.folder_button['state'] = 'normal'
            self.file_button['state'] = 'disabled'
        else:
            self.folder_button['state'] = 'disabled'
            self.file_button['state'] = 'normal'
 
    def browse_folder(self):
        folder_path = filedialog.askdirectory()
        if folder_path:
            self.path_entry.insert(0, folder_path)
            self.update_size_estimate()
 
    def browse_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg *.jpeg *.png")])
        if file_path:
            self.path_entry.insert(0, file_path)
            self.update_size_estimate()
 
    def update_quality_entry(self, value):
        self.quality_entry.delete(0, tk.END)
        self.quality_entry.insert(0, int(float(value)))
        self.update_size_estimate()
 
    def update_resize_entry(self, value):
        self.resize_entry.delete(0, tk.END)
        self.resize_entry.insert(0, int(float(value)))
        self.update_size_estimate()
 
    def update_size_estimate(self):
        if not self.path_entry.get():
            self.size_estimate_label['text'] = "估計(jì)壓縮后大小: 請(qǐng)選擇文件或文件夾"
            return
        quality_factor = float(self.quality_entry.get()) / 100
        resize_factor = (float(self.resize_entry.get()) / 100) ** 2
        if self.selection_mode.get() == "file" and os.path.isfile(self.path_entry.get()):
            original_size = os.path.getsize(self.path_entry.get())
            estimated_size = original_size * quality_factor * resize_factor
            self.size_estimate_label['text'] = f"估計(jì)壓縮后大小: {estimated_size / 1024:.2f} KB"
        elif self.selection_mode.get() == "folder" and os.path.isdir(self.path_entry.get()):
            total_size = sum(os.path.getsize(os.path.join(self.path_entry.get(), f)) for f in os.listdir(self.path_entry.get()) if os.path.isfile(os.path.join(self.path_entry.get(), f)))
            estimated_size = total_size * quality_factor * resize_factor
            self.size_estimate_label['text'] = f"估計(jì)壓縮后總大小: {estimated_size / 1024:.2f} KB"
 
    def start_compression(self):
        self.compress_button['state'] = 'disabled'
        path = self.path_entry.get()
        suffix = self.suffix_entry.get()
        if not path:
            messagebox.showerror("錯(cuò)誤", "請(qǐng)先選擇一個(gè)文件夾或圖片。")
            self.compress_button['state'] = 'enable'
            return
        try:
            quality = int(self.quality_entry.get())
            resize = int(self.resize_entry.get())
        except ValueError:
            messagebox.showerror("錯(cuò)誤", "壓縮率和縮放率必須是數(shù)字")
            self.compress_button['state'] = 'enable'
            return
 
        if self.selection_mode.get() == "folder" and os.path.isdir(path):
            self.compress_folder(path, quality, resize, suffix)
        elif self.selection_mode.get() == "file" and os.path.isfile(path):
            self.compress_image(path, quality, resize, suffix)
        else:
            messagebox.showerror("錯(cuò)誤", "所選路徑不符合當(dāng)前模式,請(qǐng)檢查。")
        self.compress_button['state'] = 'enable'
 
    def compress_folder(self, folder_path, quality, resize_percentage, suffix):
        output_folder = f"{folder_path}_{suffix}"
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)
 
        files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
        total_files = len(files)
        self.progress["maximum"] = total_files
        self.progress["value"] = 0
 
        for i, img_file in enumerate(files):
            img_path = os.path.join(folder_path, img_file)
            self.compress_image(img_path, quality, resize_percentage, output_folder)
            self.progress["value"] = i + 1
            self.master.update()
 
        messagebox.showinfo("完成", f"所有圖片已壓縮完畢,保存在 {output_folder}。")
 
    def compress_image(self, img_path, quality, resize_percentage, output_folder=None):
        img = Image.open(img_path)
        if resize_percentage != 100:
            new_size = (int(img.width * resize_percentage / 100), int(img.height * resize_percentage / 100))
            img = img.resize(new_size, Image.ANTIALIAS)
 
        if output_folder is None:
            output_folder = os.path.dirname(img_path)
        base, ext = os.path.splitext(os.path.basename(img_path))
        output_path = os.path.join(output_folder, f"{base}_{self.suffix_entry.get()}{ext}") if self.selection_mode.get() == "file" else os.path.join(output_folder, f"{base}{ext}")
 
        img.save(output_path, quality=quality)
 
 
def process():
    root = tk.Tk()
    app = ImageCompressorApp(root)
    root.mainloop()
 
if __name__ == "__main__":
    process()

以上就是Python自制圖像批量壓縮工具的詳細(xì)內(nèi)容,更多關(guān)于Python圖像批量壓縮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python基于有道實(shí)現(xiàn)英漢字典功能

    Python基于有道實(shí)現(xiàn)英漢字典功能

    這篇文章主要介紹了Python基于有道實(shí)現(xiàn)英漢字典功能的方法,通過(guò)調(diào)用有道查詢接口實(shí)現(xiàn)英漢字典功能,簡(jiǎn)單實(shí)用,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • python實(shí)現(xiàn)文件批量編碼轉(zhuǎn)換及注意事項(xiàng)

    python實(shí)現(xiàn)文件批量編碼轉(zhuǎn)換及注意事項(xiàng)

    本文通過(guò)實(shí)例代碼給大家介紹了python實(shí)現(xiàn)文件批量編碼轉(zhuǎn)換及注意事項(xiàng),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2019-10-10
  • Python pkg_resources模塊動(dòng)態(tài)加載插件實(shí)例分析

    Python pkg_resources模塊動(dòng)態(tài)加載插件實(shí)例分析

    當(dāng)編寫應(yīng)用軟件時(shí),我們通常希望程序具有一定的擴(kuò)展性,額外的功能——甚至所有非核心的功能,都能通過(guò)插件實(shí)現(xiàn),具有可插拔性。特別是使用 Python 編寫的程序,由于語(yǔ)言本身的動(dòng)態(tài)特性,為我們的插件方案提供了很多種實(shí)現(xiàn)方式
    2022-08-08
  • 在python里面運(yùn)用多繼承方法詳解

    在python里面運(yùn)用多繼承方法詳解

    在本篇文章中小編給各位分享的是關(guān)于在python里面運(yùn)用多繼承方法以及知識(shí)點(diǎn)總結(jié),有興趣的朋友們可以學(xué)習(xí)下。
    2019-07-07
  • python線程啟動(dòng)的四種方式總結(jié)

    python線程啟動(dòng)的四種方式總結(jié)

    這篇文章主要給大家介紹了關(guān)于python線程啟動(dòng)的四種方式,線程可以完成一定任務(wù),可以和其它線程共享父進(jìn)程的共享變量和部分環(huán)境,相互協(xié)作來(lái)完成任務(wù),需要的朋友可以參考下
    2024-01-01
  • Python外星人入侵游戲編程完整版

    Python外星人入侵游戲編程完整版

    這篇文章主要為大家詳細(xì)介紹了Python外星人入侵游戲編程完整的實(shí)現(xiàn)思路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Python?Flask?實(shí)現(xiàn)?HTML?文件壓縮案例代碼(9?級(jí)壓縮)

    Python?Flask?實(shí)現(xiàn)?HTML?文件壓縮案例代碼(9?級(jí)壓縮)

    這篇文章主要介紹了Python?Flask?實(shí)現(xiàn)?HTML?文件壓縮案例代碼(9?級(jí)壓縮),本案例是基于?Python?Flask?進(jìn)行搭建,所以需要提前搭建一個(gè)?Flask?項(xiàng)目環(huán)境,有?app.py?文件和?templates/index.html?文件即可,需要的朋友可以參考下
    2023-01-01
  • Tensorflow安裝問(wèn)題: Could not find a version that satisfies the requirement tensorflow

    Tensorflow安裝問(wèn)題: Could not find a version that satisfies the

    這篇文章主要介紹了Tensorflow安裝問(wèn)題: Could not find a version that satisfies the requirement tensorflow,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Python 腳本的三種執(zhí)行方式小結(jié)

    Python 腳本的三種執(zhí)行方式小結(jié)

    今天小編就為大家分享一篇Python 腳本的三種執(zhí)行方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • Python腳本完成post接口測(cè)試的實(shí)例

    Python腳本完成post接口測(cè)試的實(shí)例

    今天小編就為大家分享一篇Python腳本完成post接口測(cè)試的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12

最新評(píng)論

临漳县| 洛隆县| 汤原县| 刚察县| 绩溪县| 肇庆市| 永康市| 青川县| 松江区| 邹城市| 诏安县| 信丰县| 红河县| 南和县| 台中市| 福鼎市| 镇原县| 定远县| 贺州市| 滦平县| 玉山县| 新平| 望江县| 上思县| 沂水县| 闵行区| 本溪市| 韩城市| 公主岭市| 苍山县| 沅陵县| 大连市| 苏尼特右旗| 隆德县| 平邑县| 壤塘县| 文安县| 兴文县| 外汇| 叶城县| 游戏|