小庚资源网 · 免费提供绿色软件、活动线报以及其他网络资源,好货不私藏!
当前位置:网站首页 > 网站源码 > 只有源码 >正文

修改图片分辨率的工具Python源码

作者:小编日期:2026-01-16浏览:4738分类:只有源码

  1. import tkinter as tk

  2. from tkinter import ttk, filedialog, messagebox

  3. from PIL import Image

  4. import os

  5. class ImageResizerApp:

  6.     def __init__(self, root):

  7.         self.root = root

  8.         self.root.title("图片分辨率修改工具")

  9.         self.root.geometry("800x650")

  10.         self.root.configure(bg="#f0f0f0")

  11.         self.image_paths = []

  12.         self.target_width = tk.IntVar(value=800)

  13.         self.target_height = tk.IntVar(value=600)

  14.         self.keep_aspect_ratio = tk.BooleanVar(value=True)

  15.         self.output_path = ""  

  16.         self.setup_ui()

  17.     def setup_ui(self):

  18.         title_label = tk.Label(

  19.             self.root,

  20.             text="图片分辨率修改工具",

  21.             font=("Arial", 18, "bold"),

  22.             bg="#f0f0f0",

  23.             fg="#333"

  24.         )

  25.         title_label.pack(pady=15)

  26.         main_frame = tk.Frame(self.root, bg="#f0f0f0")

  27.         main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)

  28.         control_frame = tk.LabelFrame(

  29.             main_frame,

  30.             text="控制面板",

  31.             font=("Arial", 12),

  32.             bg="#f0f0f0",

  33.             fg="#333",

  34.             padx=10,

  35.             pady=10

  36.         )

  37.         control_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))

  38.         resolution_frame = tk.LabelFrame(

  39.             control_frame,

  40.             text="分辨率设置",

  41.             font=("Arial", 10),

  42.             bg="#f0f0f0",

  43.             fg="#333"

  44.         )

  45.         resolution_frame.pack(fill=tk.X, pady=(0, 15))

  46.         width_frame = tk.Frame(resolution_frame, bg="#f0f0f0")

  47.         width_frame.pack(fill=tk.X, pady=5)

  48.         tk.Label(width_frame, text="宽度:", font=("Arial", 10), bg="#f0f0f0").pack(side=tk.LEFT)

  49.         width_entry = tk.Entry(

  50.             width_frame,

  51.             textvariable=self.target_width,

  52.             font=("Arial", 10),

  53.             width=10

  54.         )

  55.         width_entry.pack(side=tk.RIGHT)

  56.         height_frame = tk.Frame(resolution_frame, bg="#f0f0f0")

  57.         height_frame.pack(fill=tk.X, pady=5)

  58.         tk.Label(height_frame, text="高度:", font=("Arial", 10), bg="#f0f0f0").pack(side=tk.LEFT)

  59.         height_entry = tk.Entry(

  60.             height_frame,

  61.             textvariable=self.target_height,

  62.             font=("Arial", 10),

  63.             width=10

  64.         )

  65.         height_entry.pack(side=tk.RIGHT)

  66.         aspect_check = tk.Checkbutton(

  67.             resolution_frame,

  68.             text="保持原始宽高比",

  69.             variable=self.keep_aspect_ratio,

  70.             font=("Arial", 10),

  71.             bg="#f0f0f0"

  72.         )

  73.         aspect_check.pack(pady=5)

  74.         io_frame = tk.LabelFrame(

  75.             control_frame,

  76.             text="导入导出设置",

  77.             font=("Arial", 10),

  78.             bg="#f0f0f0",

  79.             fg="#333"

  80.         )

  81.         io_frame.pack(fill=tk.X, pady=10)

  82.         

  83.         tk.Label(io_frame, text="导入图片:", font=("Arial", 10), bg="#f0f0f0").pack(anchor=tk.W, pady=(0, 5))

  84.         self.import_path_var = tk.StringVar(value="未选择")

  85.         import_path_label = tk.Label(

  86.             io_frame,

  87.             textvariable=self.import_path_var,

  88.             font=("Arial", 9),

  89.             bg="#ffffff",

  90.             relief=tk.SUNKEN,

  91.             anchor=tk.W

  92.         )

  93.         import_path_label.pack(fill=tk.X, pady=(0, 5))

  94.         

  95.         import_btn = tk.Button(

  96.             io_frame,

  97.             text="导入图片",

  98.             command=self.import_images,

  99.             bg="#4CAF50",

  100.             fg="white",

  101.             font=("Arial", 10, "bold"),

  102.             relief=tk.FLAT,

  103.             padx=10,

  104.             pady=5

  105.         )

  106.         import_btn.pack(fill=tk.X, pady=5)

  107.         tk.Label(io_frame, text="输出路径:", font=("Arial", 10), bg="#f0f0f0").pack(anchor=tk.W, pady=(0, 5))

  108.         self.output_path_var = tk.StringVar(value="未选择")

  109.         output_path_label = tk.Label(

  110.             io_frame,

  111.             textvariable=self.output_path_var,

  112.             font=("Arial", 9),

  113.             bg="#ffffff",

  114.             relief=tk.SUNKEN,

  115.             anchor=tk.W

  116.         )

  117.         output_path_label.pack(fill=tk.X, pady=(0, 5))

  118.         

  119.         select_output_btn = tk.Button(

  120.             io_frame,

  121.             text="选择输出路径",

  122.             command=self.select_output_path,

  123.             bg="#9C27B0",

  124.             fg="white",

  125.             font=("Arial", 10, "bold"),

  126.             relief=tk.FLAT,

  127.             padx=10,

  128.             pady=3

  129.         )

  130.         select_output_btn.pack(fill=tk.X)

  131.         button_frame = tk.Frame(control_frame, bg="#f0f0f0")

  132.         button_frame.pack(fill=tk.X, pady=10)

  133.         start_btn = tk.Button(

  134.             button_frame,

  135.             text="开始处理",

  136.             command=self.start_processing,

  137.             bg="#2196F3",

  138.             fg="white",

  139.             font=("Arial", 10, "bold"),

  140.             relief=tk.FLAT,

  141.             padx=10,

  142.             pady=5

  143.         )

  144.         start_btn.pack(fill=tk.X, pady=5)

  145.         reset_btn = tk.Button(

  146.             button_frame,

  147.             text="重置",

  148.             command=self.reset,

  149.             bg="#FF9800",

  150.             fg="white",

  151.             font=("Arial", 10, "bold"),

  152.             relief=tk.FLAT,

  153.             padx=10,

  154.             pady=5

  155.         )

  156.         reset_btn.pack(fill=tk.X, pady=5)

  157.         exit_btn = tk.Button(

  158.             button_frame,

  159.             text="退出",

  160.             command=self.root.quit,

  161.             bg="#f44336",

  162.             fg="white",

  163.             font=("Arial", 10, "bold"),

  164.             relief=tk.FLAT,

  165.             padx=10,

  166.             pady=5

  167.         )

  168.         exit_btn.pack(fill=tk.X, pady=5)

  169.         list_frame = tk.LabelFrame(

  170.             main_frame,

  171.             text="图片列表",

  172.             font=("Arial", 12),

  173.             bg="#f0f0f0",

  174.             fg="#333",

  175.             padx=10,

  176.             pady=10

  177.         )

  178.         list_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

  179.         columns = ('filename', 'original_size', 'format')

  180.         self.tree = ttk.Treeview(list_frame, columns=columns, show='headings', height=5)  

  181.         self.tree.heading('filename', text='文件名')

  182.         self.tree.heading('original_size', text='原始尺寸')

  183.         self.tree.heading('format', text='格式')

  184.         self.tree.column('filename', width=200)

  185.         self.tree.column('original_size', width=100)

  186.         self.tree.column('format', width=80)

  187.         scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)

  188.         self.tree.configure(yscrollcommand=scrollbar.set)

  189.         

  190.         self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

  191.         scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

  192.         

  193.     def import_images(self):

  194.         supported_formats = [

  195.             ("All Supported Images", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff;*.webp;*.ico"),

  196.             ("JPEG", "*.jpg;*.jpeg"),

  197.             ("PNG", "*.png"),

  198.             ("BMP", "*.bmp"),

  199.             ("GIF", "*.gif"),

  200.             ("TIFF", "*.tiff"),

  201.             ("WEBP", "*.webp"),

  202.             ("All Files", "*.*")

  203.         ]

  204.         

  205.         filenames = filedialog.askopenfilenames(

  206.             title="选择图片文件",

  207.             filetypes=supported_formats

  208.         )

  209.         

  210.         if filenames:

  211.             for filename in filenames:

  212.                 if filename not in self.image_paths:

  213.                     self.image_paths.append(filename)

  214.             if len(filenames) > 1:

  215.                 directories = set(os.path.dirname(path) for path in filenames)

  216.                 if len(directories) == 1:

  217.                     common_dir = list(directories)[0]

  218.                     display_text = f"来自同目录: {os.path.basename(common_dir)} ({len(filenames)}张)"

  219.                 else:

  220.                     display_text = f"多目录导入 ({len(filenames)}张)"

  221.                 self.import_path_var.set(display_text)

  222.             elif len(filenames) == 1:

  223.                 self.import_path_var.set(os.path.dirname(filenames[0]))

  224.             else:

  225.                 self.import_path_var.set("未选择")

  226.             

  227.             self.refresh_image_list()

  228.     def refresh_image_list(self):

  229.         for item in self.tree.get_children():

  230.             self.tree.delete(item)

  231.         

  232.         for path in self.image_paths:

  233.             try:

  234.                 img = Image.open(path)

  235.                 size_str = f"{img.width}x{img.height}"

  236.                 format_str = img.format or "Unknown"

  237.                 filename = os.path.basename(path)

  238.                

  239.                 self.tree.insert('', tk.END, values=(filename, size_str, format_str))

  240.             except Exception as e:

  241.                 print(f"无法读取图片 {path}: {e}")

  242.     def start_processing(self):

  243.         if not self.image_paths:

  244.             messagebox.showwarning("警告", "请先导入图片!")

  245.             return

  246.         

  247.         if not self.output_path:

  248.             self.output_path = filedialog.askdirectory(title="选择输出目录")

  249.             if not self.output_path:

  250.                 return

  251.             self.output_path_var.set(self.output_path)

  252.         

  253.         target_w = self.target_width.get()

  254.         target_h = self.target_height.get()

  255.         

  256.         if target_w <= 0 or target_h <= 0:

  257.             messagebox.showerror("错误", "请输入有效的分辨率值!")

  258.             return

  259.         

  260.         success_count = 0

  261.         error_count = 0

  262.         

  263.         for img_path in self.image_paths:

  264.             try:

  265.                 with Image.open(img_path) as img:

  266.                     original_size = img.size

  267.                     if self.keep_aspect_ratio.get():

  268.                         original_ratio = original_size[0] / original_size[1]

  269.                         target_ratio = target_w / target_h

  270.                         

  271.                         if original_ratio > target_ratio:

  272.                             new_width = target_w

  273.                             new_height = int(target_w / original_ratio)

  274.                         else:

  275.                             new_height = target_h

  276.                             new_width = int(target_h * original_ratio)

  277.                         

  278.                         resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)

  279.                     else:

  280.                         resized_img = img.resize((target_w, target_h), Image.Resampling.LANCZOS)

  281.                     

  282.                     base_name = os.path.splitext(os.path.basename(img_path))[0]

  283.                     extension = os.path.splitext(img_path)[1]

  284.                     output_path = os.path.join(self.output_path, f"{base_name}{extension}")

  285.                     

  286.                     counter = 1

  287.                     original_output_path = output_path

  288.                     while os.path.exists(output_path):

  289.                         name_part = os.path.splitext(original_output_path)[0]

  290.                         ext_part = os.path.splitext(original_output_path)[1]

  291.                         output_path = f"{name_part}_resized_{counter}{ext_part}"

  292.                         counter += 1

  293.                     

  294.                     resized_img.save(output_path, optimize=True, quality=95)

  295.                     success_count += 1

  296.                     

  297.             except Exception as e:

  298.                 print(f"处理图片失败 {img_path}: {e}")

  299.                 error_count += 1

  300.         

  301.         messagebox.showinfo(

  302.             "处理完成",

  303.             f"成功处理 {success_count} 张图片\n{error_count} 张图片处理失败"

  304.         )

  305.     def reset(self):

  306.         self.image_paths.clear()

  307.         self.target_width.set(800)

  308.         self.target_height.set(600)

  309.         self.keep_aspect_ratio.set(True)

  310.         self.output_path = ""

  311.         self.output_path_var.set("未选择")

  312.         self.refresh_image_list()

  313.    

  314.     def select_output_path(self):

  315.         """选择输出路径"""

  316.         selected_path = filedialog.askdirectory(title="选择输出目录")

  317.         if selected_path:

  318.             self.output_path = selected_path

  319.             self.output_path_var.set(selected_path)

  320. if __name__ == "__main__":

  321.     root = tk.Tk()

  322.     app = ImageResizerApp(root)

  323.     root.mainloop()

因为工作需要,要改各种尺寸的图片,用 ps 修改之后,发现与我修改的还是不太一样,于是就有了这个代码,可以写好尺寸一键修改,并且可以导入多张图片
款式就是这几样的:

image.png

暂无评论,来添加一个吧。

取消回复欢迎发表评论:

Copyright© XGW9.COM版权所有〖小庚资源网〗
〖恒创科技〗为本站提供专业云计算服务  
本站发布的内容来源于互联网,如果有侵权内容,请联系我们删除!E-mail:xgzyw6@outlook.com
关于我们|我要投稿|免责声明|XML地图