欢迎!我白天是个邮递员,晚上就是个有抱负的演员。这是我的网站。我住在天朝的帝都,有条叫做Jack的狗。
一段批量修改照片文件大小Python脚本,输入和输出图片文件夹,图片你的最大和最小标准,批量调整照片文件大小。
# 设定图片大小有效import osimport threadingimport loggingfrom tkinter import Tk, Button, Label, Entry, Text, Scrollbar, filedialog, messageboxfrom tkinter.ttk import Progressbarfrom PIL import Image, ImageDraw, ImageFontimport numpy as npdef 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()
