吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1632|回复: 24
收起左侧

[Python 原创] 批量调整照片文件大小

[复制链接]
52pojie886 发表于 2024-8-24 15:43
本帖最后由 苏紫方璇 于 2024-8-26 12:12 编辑

输入和输出图片文件夹,图片你的最大和最小标准,批量调整照片文件大小
1-4mb之间是好使的

# 设定图片大小有效
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()

界面

界面

免费评分

参与人数 5吾爱币 +5 热心值 +5 收起 理由
pjj811885 + 1 + 1 我很赞同!
vicmay + 1 + 1 我很赞同!
haopengyou + 1 + 1 谢谢@Thanks!
haiyangnanzi + 1 + 1 谢谢@Thanks!
grrr_zhao + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

liuganglove2018 发表于 2024-8-24 22:06
楼上,你说的是哪个英文,UI上那几个单词非常简单,至于代码部分,也没有很难的,几乎都是变量名,保留字。这些都看不懂,用易语言也行
c32396242 发表于 2024-8-24 20:28
tanding004 发表于 2024-8-24 20:57
huakai200 发表于 2024-8-24 21:25
英文的 看着不方便
loquat 发表于 2024-8-24 21:48
表示挺厉害的
long8586 发表于 2024-8-24 21:56
难道不是批量修改图片大小?有点绕啊
yytang225 发表于 2024-8-24 22:04
厉害啊啊
枫叶飞向海 发表于 2024-8-24 22:07
研究研究,感谢
wmufo123 发表于 2024-8-24 22:19
老铁  中国人不能搞中文吗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-12 12:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表