|
|
import os |
|
|
from tqdm import tqdm |
|
|
from concurrent.futures import ProcessPoolExecutor |
|
|
import multiprocessing |
|
|
import subprocess |
|
|
import cv2 |
|
|
from PIL import Image |
|
|
|
|
|
|
|
|
input_dir = '/Users/gohyunjun/Downloads/unprocessed_1007' |
|
|
output_dir = '/Users/gohyunjun/Downloads/unprocessed_1007_optim' |
|
|
|
|
|
|
|
|
if not os.path.exists(output_dir): |
|
|
os.makedirs(output_dir) |
|
|
|
|
|
|
|
|
def resize_image_with_aspect_ratio_cv(img, target_width, target_height): |
|
|
original_height, original_width = img.shape[:2] |
|
|
ratio = min(target_width / original_width, target_height / original_height) |
|
|
new_width = int(original_width * ratio) |
|
|
new_height = int(original_height * ratio) |
|
|
return cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_LANCZOS4) |
|
|
|
|
|
|
|
|
def compress_with_pngquant(output_path): |
|
|
try: |
|
|
|
|
|
subprocess.run(['pngquant', '--force', '--ext', '.png', '--quality', '65-80', output_path], check=True) |
|
|
print(f"Compressed with pngquant: {output_path}") |
|
|
except subprocess.CalledProcessError as e: |
|
|
print(f"An error occurred with pngquant on {output_path}: {e}") |
|
|
|
|
|
|
|
|
def compress_and_resize_image(args): |
|
|
input_path, output_path = args |
|
|
try: |
|
|
|
|
|
img = cv2.imread(input_path, cv2.IMREAD_UNCHANGED) |
|
|
|
|
|
|
|
|
img = resize_image_with_aspect_ratio_cv(img, 800, 450) |
|
|
|
|
|
|
|
|
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) |
|
|
|
|
|
|
|
|
img_pil.save(output_path, format='PNG', optimize=True) |
|
|
|
|
|
|
|
|
compress_with_pngquant(output_path) |
|
|
|
|
|
except Exception as e: |
|
|
print(f"An error occurred with {input_path}: {e}") |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
image_files = [f for f in os.listdir(input_dir) if f.lower().endswith('.png')] |
|
|
|
|
|
|
|
|
tasks = [] |
|
|
for filename in image_files: |
|
|
input_path = os.path.join(input_dir, filename) |
|
|
output_path = os.path.join(output_dir, filename) |
|
|
tasks.append((input_path, output_path)) |
|
|
|
|
|
|
|
|
num_workers = multiprocessing.cpu_count() * 2 |
|
|
|
|
|
|
|
|
with ProcessPoolExecutor(max_workers=num_workers) as executor: |
|
|
list(tqdm(executor.map(compress_and_resize_image, tasks), total=len(tasks), desc="Processing images")) |
|
|
|
|
|
print('All images have been processed.') |
|
|
|