python教程

批量修改照片文件大小Python脚本

我的站长站 2024-08-28 人阅读

一段批量修改照片文件大小Python脚本,输入和输出图片文件夹,图片你的最大和最小标准,批量调整照片文件大小。

# 设定图片大小有效
import os
import threading
import logging
from tkinter import Tk, Button, Label, Entry, Text, Scrollbar, filedialog, messagebox
from tkinter.ttk import Progressbar
from PIL import Image, ImageDraw, ImageFont
import numpy as np
def setup_logging(output_dir):
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    log_file = os.path.join(output_dir, 'process_log.txt')
    logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def resize_to_resolution(image_path, output_path, target_resolution, min_size_kb, max_size_kb):
    with Image.open(image_path) as img:
        img = img.resize(target_resolution, Image.LANCZOS)
        img.save(output_path, format='PNG')
        ensure_image_size_range(output_path, min_size_kb, max_size_kb)
def embed_image(original_image_path, hidden_image_path, output_path, min_size_kb, max_size_kb):
    origin_img = Image.open(original_image_path)
    hidden_img = Image.open(hidden_image_path)
    origin_data = np.array(origin_img)
    hidden_data = np.array(hidden_img)
    # 确保隐藏图片的大小小于原图片大小
    hidden_data = hidden_data[:origin_data.shape[0], :origin_data.shape[1], :]
    # 融合数据
    for row in range(hidden_data.shape[0]):
        for col in range(hidden_data.shape[1]):
            for channel in range(3):  # 遍历RGB三个通道
                origin_data[row, col, channel] = (origin_data[row, col, channel] & 0xFE) | (
                    hidden_data[row, col, channel] >> 7)
    embedded_image = Image.fromarray(origin_data)
    draw_text(embedded_image, "我爱peiniu")  
    embedded_image.save(output_path, format='PNG')
    ensure_image_size_range(output_path, min_size_kb, max_size_kb)
def generate_large_image(size_kb, output_path):
    # 生成一个指定大小的随机图像
    width = int(np.sqrt(size_kb * 1024 / 3))  # 假设每个像素3字节(RGB)
    height = width
    random_image_data = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8)
    hidden_image = Image.fromarray(random_image_data)
    hidden_image.save(output_path, format='PNG')
def draw_text(image, text):
    draw = ImageDraw.Draw(image)
    font_size = max(10, image.size[0] // 100)
    font = ImageFont.truetype("arial.ttf", font_size)
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width, text_height = bbox[2] - bbox[0], bbox[3] - bbox[1]
    position = (image.size[0] - text_width - 10, image.size[1] - text_height - 10)  # 右下角
    draw.text(position, text, (255, 255, 255), font=font)
def process_images(input_dir, output_dir, min_size_kb, max_size_kb):
    setup_logging(output_dir)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    hidden_image_path = os.path.join(output_dir, 'hidden_image.png')
    generate_large_image(min_size_kb, hidden_image_path)  # 生成一个指定大小的隐藏图片
    image_files = [f for f in os.listdir(input_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
    total_files = len(image_files)
    log_text.insert('end', f"Processing {total_files} images...\n")
    progress_bar["maximum"] = total_files
    success_count = 0
    error_count = 0
    for i, filename in enumerate(image_files):
        input_path = os.path.join(input_dir, filename)
        temp_path = os.path.join(output_dir, 'temp_' + filename)
        output_path = os.path.join(output_dir, filename.replace('.jpg', '.png').replace('.jpeg', '.png'))  # 确保输出为PNG格式
        try:
            file_size_kb = os.path.getsize(input_path) / 1024
            if file_size_kb < 100:
                # 调整分辨率为4000x3000
                resize_to_resolution(input_path, temp_path, (4000, 3000), min_size_kb, max_size_kb)
                # 对于小于100KB的图片,嵌入生成的950KB图片
                embed_image(temp_path, hidden_image_path, output_path, min_size_kb, max_size_kb)
                os.remove(temp_path)  # 删除临时文件
                logging.info(f"Processed {filename} successfully h.")
                log_text.insert('end', f"Processed {filename} successfully h.\n")
            else:
                image = Image.open(input_path)
                draw_text(image, "我爱peiniu")  
                image.save(output_path, format='PNG')
                ensure_image_size_range(output_path, min_size_kb, max_size_kb)
                logging.info(f"Processed {filename} successfully and converted to PNG format.")
                log_text.insert('end', f"Processed {filename} successfully and converted to PNG format.\n")
            success_count += 1
        except Exception as e:
            logging.error(f"Error processing {filename}: {e}")
            log_text.insert('end', f"Error processing {filename}: {e}\n")
            error_count += 1
        progress_bar["value"] = i + 1
        root.update_idletasks()
    summary = f"Processing completed!\nTotal files: {total_files}\nSuccessfully processed: {success_count}\nErrors: {error_count}"
    messagebox.showinfo("Processing Summary", summary)
    log_text.insert('end', summary + "\n")
def resize_image(input_path, output_path, max_size_kb):
    image = Image.open(input_path)
    target_resolution = (4000, 3000)
    while True:
        image = image.resize(target_resolution, Image.LANCZOS)
        image.save(output_path, format='PNG')
        if os.path.getsize(output_path) <= max_size_kb * 1024:
            break
        target_resolution = (int(target_resolution[0] * 0.9), int(target_resolution[1] * 0.9))
def ensure_image_size_range(image_path, min_size_kb, max_size_kb):
    while True:
        size_kb = os.path.getsize(image_path) / 1024
        if min_size_kb <= size_kb <= max_size_kb:
            break
        if size_kb < min_size_kb:
            increase_image_size(image_path)
        elif size_kb > max_size_kb:
            reduce_image_size(image_path)
def increase_image_size(image_path):
    image = Image.open(image_path)
    width, height = image.size
    new_size = (int(width * 1.1), int(height * 1.1))
    image = image.resize(new_size, Image.LANCZOS)
    image.save(image_path, format='PNG')
def reduce_image_size(image_path):
    image = Image.open(image_path)
    width, height = image.size
    new_size = (int(width * 0.9), int(height * 0.9))
    image = image.resize(new_size, Image.LANCZOS)
    image.save(image_path, format='PNG')
def select_input_dir():
    input_dir = filedialog.askdirectory()
    input_dir_entry.delete(0, 'end')
    input_dir_entry.insert(0, input_dir)
def select_output_dir():
    output_dir = filedialog.askdirectory()
    output_dir_entry.delete(0, 'end')
    output_dir_entry.insert(0, output_dir)
def start_processing():
    input_dir = input_dir_entry.get()
    output_dir = output_dir_entry.get()
    min_size = int(min_size_entry.get())
    max_size = int(max_size_entry.get())
    if not input_dir or not output_dir or not min_size or not max_size:
        messagebox.showerror("Error", "Please fill all fields.")
        return
    log_text.delete(1.0, 'end')
    # 创建一个新的线程来处理图像处理任务
    threading.Thread(target=process_images, args=(input_dir, output_dir, min_size, max_size)).start()
# 创建Tkinter窗口
root = Tk()
root.title("Image Processing Tool")
# 输入目录选择
Label(root, text="Input Directory:").grid(row=0, column=0, padx=10, pady=5, sticky='e')
input_dir_entry = Entry(root, width=50)
input_dir_entry.grid(row=0, column=1, padx=10, pady=5)
Button(root, text="Browse", command=select_input_dir).grid(row=0, column=2, padx=10, pady=5)
# 输出目录选择
Label(root, text="Output Directory:").grid(row=1, column=0, padx=10, pady=5, sticky='e')
output_dir_entry = Entry(root, width=50)
output_dir_entry.grid(row=1, column=1, padx=10, pady=5)
Button(root, text="Browse", command=select_output_dir).grid(row=1, column=2, padx=10, pady=5)
# 最小大小输入
Label(root, text="Min Size (KB):").grid(row=2, column=0, padx=10, pady=5, sticky='e')
min_size_entry = Entry(root, width=20)
min_size_entry.grid(row=2, column=1, padx=10, pady=5, sticky='w')
# 最大大小输入
Label(root, text="Max Size (KB):").grid(row=3, column=0, padx=10, pady=5, sticky='e')
max_size_entry = Entry(root, width=20)
max_size_entry.grid(row=3, column=1, padx=10, pady=5, sticky='w')
# 开始处理按钮
Button(root, text="Start Processing", command=start_processing).grid(row=4, column=1, pady=20)
# 进度条
progress_bar = Progressbar(root, orient='horizontal', mode='determinate')
progress_bar.grid(row=5, column=0, columnspan=3, padx=10, pady=5, sticky='we')
# 日志信息显示框
log_text = Text(root, wrap='word', height=10, width=80)
log_text.grid(row=6, column=0, columnspan=3, padx=10, pady=10)
scrollbar = Scrollbar(root, command=log_text.yview)
scrollbar.grid(row=6, column=3, pady=10, sticky='ns')
log_text['yscrollcommand'] = scrollbar.set
# 启动Tkinter主循环
root.mainloop()


相关推荐
  • Python脚本
  • 监测腾讯云轻量服务器流量超标关机python脚本

    脚本介绍一款监测腾讯云轻量应用服务器流量包使用情况,并根据配置进行警告和关机的Python脚本。GitHub:https://github.com/XiaoXinYo/Tencent_Cloud_LightHouse_Server_Guardian脚本功能仅用于轻量级服务器1.自动检测流量包剩余,可设置使用比2.自动关...

    python教程 92 2年前
  • Python无需认证QQ扫码登录脚本

    无需认证QQ扫码登录脚本python脚本,盗用JD的QQ登录,也可以改成其他网址。无需自己注册腾讯开发者,无需自己有一套网址去申请应用Get_QQ返回QQ号,也可以获取到QQ头像、好友等其他信息,请勿用于非法行为import requestsimport timefrom PIL import Imagedef...

    python教程 345 3年前
  • 最新python织梦dedecms远程执行脚本

    织梦CMS是使用最多的CMS之 一,但是漏洞也非常多。分享一款python写的织梦远程文件包含漏洞。修复此漏洞方法,请见文章底部。织梦CMS漏洞代码#! /usr/bin/env python#coding=utf-8#Joseph(小续)import requestsimport sysimport redef main():try:url="...

    服务器配置 295 4年前
最新更新