Upload optim.py
Browse files
optim.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from tqdm import tqdm
|
| 3 |
+
from concurrent.futures import ProcessPoolExecutor
|
| 4 |
+
import multiprocessing
|
| 5 |
+
import subprocess
|
| 6 |
+
import cv2
|
| 7 |
+
from PIL import Image
|
| 8 |
+
|
| 9 |
+
# 이미지 파일 경로 설정
|
| 10 |
+
input_dir = '/Users/gohyunjun/Downloads/unprocessed_1007' # 원본 이미지 폴더 경로
|
| 11 |
+
output_dir = '/Users/gohyunjun/Downloads/unprocessed_1007_optim' # 최적화된 이미지 저장 경로
|
| 12 |
+
|
| 13 |
+
# 디렉토리가 없으면 생성
|
| 14 |
+
if not os.path.exists(output_dir):
|
| 15 |
+
os.makedirs(output_dir)
|
| 16 |
+
|
| 17 |
+
# 이미지 리사이즈 함수 (비율 유지, 라코스 보간법 사용)
|
| 18 |
+
def resize_image_with_aspect_ratio_cv(img, target_width, target_height):
|
| 19 |
+
original_height, original_width = img.shape[:2]
|
| 20 |
+
ratio = min(target_width / original_width, target_height / original_height)
|
| 21 |
+
new_width = int(original_width * ratio)
|
| 22 |
+
new_height = int(original_height * ratio)
|
| 23 |
+
return cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_LANCZOS4)
|
| 24 |
+
|
| 25 |
+
# pngquant로 압축하는 함수
|
| 26 |
+
def compress_with_pngquant(output_path):
|
| 27 |
+
try:
|
| 28 |
+
# pngquant를 호출하여 이미지 압축 ( --force로 기존 파일 덮어쓰기, --ext로 확장자 지정)
|
| 29 |
+
subprocess.run(['pngquant', '--force', '--ext', '.png', '--quality', '65-80', output_path], check=True)
|
| 30 |
+
print(f"Compressed with pngquant: {output_path}")
|
| 31 |
+
except subprocess.CalledProcessError as e:
|
| 32 |
+
print(f"An error occurred with pngquant on {output_path}: {e}")
|
| 33 |
+
|
| 34 |
+
# 이미지 처리 함수
|
| 35 |
+
def compress_and_resize_image(args):
|
| 36 |
+
input_path, output_path = args
|
| 37 |
+
try:
|
| 38 |
+
# OpenCV로 이미지 읽기
|
| 39 |
+
img = cv2.imread(input_path, cv2.IMREAD_UNCHANGED)
|
| 40 |
+
|
| 41 |
+
# 이미지 리사이즈 (비율 유지)
|
| 42 |
+
img = resize_image_with_aspect_ratio_cv(img, 800, 450)
|
| 43 |
+
|
| 44 |
+
# OpenCV에서 읽은 이미지를 RGB로 변환
|
| 45 |
+
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
|
| 46 |
+
|
| 47 |
+
# PNG로 저장 (원본 파일, 나중에 pngquant로 압축)
|
| 48 |
+
img_pil.save(output_path, format='PNG', optimize=True)
|
| 49 |
+
|
| 50 |
+
# pngquant로 이미지 압축
|
| 51 |
+
compress_with_pngquant(output_path)
|
| 52 |
+
|
| 53 |
+
except Exception as e:
|
| 54 |
+
print(f"An error occurred with {input_path}: {e}")
|
| 55 |
+
|
| 56 |
+
if __name__ == "__main__":
|
| 57 |
+
# 입력 디렉토리의 모든 PNG 파일에 대해 실행
|
| 58 |
+
image_files = [f for f in os.listdir(input_dir) if f.lower().endswith('.png')]
|
| 59 |
+
|
| 60 |
+
# 입력 및 출력 경로 생성
|
| 61 |
+
tasks = []
|
| 62 |
+
for filename in image_files:
|
| 63 |
+
input_path = os.path.join(input_dir, filename)
|
| 64 |
+
output_path = os.path.join(output_dir, filename)
|
| 65 |
+
tasks.append((input_path, output_path))
|
| 66 |
+
|
| 67 |
+
# 워커 수를 코어 수의 2배로 설정
|
| 68 |
+
num_workers = multiprocessing.cpu_count() * 2
|
| 69 |
+
|
| 70 |
+
# 프로세스 풀 생성 및 작업 병렬 실행
|
| 71 |
+
with ProcessPoolExecutor(max_workers=num_workers) as executor:
|
| 72 |
+
list(tqdm(executor.map(compress_and_resize_image, tasks), total=len(tasks), desc="Processing images"))
|
| 73 |
+
|
| 74 |
+
print('All images have been processed.')
|