111 lines
3.8 KiB
Python
111 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import subprocess
|
|
import json
|
|
|
|
# Standard crop for 1300x1733 images (banner is ~400px tall)
|
|
CROP_TOP_400 = 400 # Main category images
|
|
CROP_TOP_80 = 80 # Smaller banners
|
|
SKIP_CROP = 0
|
|
|
|
# Special: (crop_top, crop_bottom) for images needing both top and bottom crop
|
|
CROP_BOTH = "both"
|
|
|
|
IMAGES_WITH_BANNERS = [
|
|
# Main category images (1300x1733, 400px top banner)
|
|
("2021/03/durgo_000C.jpg", CROP_TOP_400),
|
|
("2021/03/valve_000C.jpg", (400, 400)), # Has "Valve KITZ" at bottom too
|
|
("2021/03/water-pump_000C.jpg", CROP_TOP_400),
|
|
("2021/03/water-treatment_000C.jpg", CROP_TOP_400),
|
|
("2021/03/grilles_000C.jpg", CROP_TOP_400),
|
|
("2021/03/realflex_000C.jpg", CROP_TOP_400),
|
|
("2021/03/extinguishers_000C.jpg", CROP_TOP_400),
|
|
("2025/01/fencing_000C.jpg", CROP_TOP_400),
|
|
("2025/01/balljet-cover_000C.jpg", CROP_TOP_400),
|
|
("2025/01/thermobrek_cover_000C.jpg", CROP_TOP_400),
|
|
("2025/01/pipe-and-other_000.jpg", CROP_TOP_400),
|
|
("2025/01/pipe-coupling-machine_000.jpg", CROP_TOP_400),
|
|
("2025/01/Hanger-Clamp-Bolt_000.jpg", CROP_TOP_400),
|
|
("2025/09/IMG-cover-309251.png", CROP_TOP_400),
|
|
# Pipe subcategory images (1300x1733, 400px top banner)
|
|
("2021/03/ppr-pipe_000C.jpg", CROP_TOP_400),
|
|
("2021/03/hdpe-pipe_000C.jpg", CROP_TOP_400),
|
|
("2021/03/upvc-pipe_000C.jpg", CROP_TOP_400),
|
|
("2021/03/poloplast_000C.jpg", CROP_TOP_400),
|
|
("2021/03/syler_000C.jpg", CROP_TOP_400),
|
|
("2021/03/pvc-pipe_000C.jpg", CROP_TOP_400),
|
|
("2021/03/xylent_000C.jpg", (400, 400)), # Has "เงียบ! 22 dB" at bottom
|
|
("2021/03/hdpe-welding_000C-1.jpg", CROP_TOP_400),
|
|
# Hanger images (different dimensions, 400px top banner)
|
|
("2024/02/ADJUSTABLE_SPLIT_RING_HANGER_cover_01.jpg", CROP_TOP_400),
|
|
("2024/02/ADJUSTABLE_CLEVIS_HANGER_cover_01.jpg", CROP_TOP_400),
|
|
("2024/02/THREADED_ROD_cover_01.jpg", CROP_TOP_400),
|
|
# Special cases - skip for now, handle separately
|
|
("2021/02/Valve-KITZ.jpg", SKIP_CROP), # 800x648, different layout
|
|
("2021/02/Grilles01logo.jpg", CROP_TOP_80),
|
|
("2021/02/Banner-HDPE-wel-1024x382.jpg", SKIP_CROP), # Side text
|
|
]
|
|
|
|
BASE_DIR = "/Users/kunthawatgreethong/Gitea/dealplustech/public/images"
|
|
OUTPUT_DIR = "/Users/kunthawatgreethong/Gitea/dealplustech/public/images-clean"
|
|
|
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
|
|
|
|
|
def get_dimensions(img_path):
|
|
result = subprocess.run(
|
|
["identify", "-format", "%w %h", img_path], capture_output=True, text=True
|
|
)
|
|
w, h = result.stdout.strip().split()
|
|
return int(w), int(h)
|
|
|
|
|
|
def crop_image(input_path, output_path, crop_amount):
|
|
if crop_amount == 0:
|
|
subprocess.run(["cp", input_path, output_path], check=True)
|
|
return
|
|
|
|
w, h = get_dimensions(input_path)
|
|
|
|
if isinstance(crop_amount, tuple):
|
|
crop_top, crop_bottom = crop_amount
|
|
new_h = h - crop_top - crop_bottom
|
|
cmd = [
|
|
"magick",
|
|
"convert",
|
|
input_path,
|
|
"-crop",
|
|
f"{w}x{new_h}+0+{crop_top}",
|
|
"+repage",
|
|
output_path,
|
|
]
|
|
else:
|
|
new_h = h - crop_amount
|
|
cmd = [
|
|
"magick",
|
|
"convert",
|
|
input_path,
|
|
"-crop",
|
|
f"{w}x{new_h}+0+{crop_amount}",
|
|
"+repage",
|
|
output_path,
|
|
]
|
|
subprocess.run(cmd, check=True)
|
|
|
|
|
|
for rel_path, crop_amount in IMAGES_WITH_BANNERS:
|
|
input_path = os.path.join(BASE_DIR, rel_path)
|
|
output_path = os.path.join(OUTPUT_DIR, os.path.basename(rel_path))
|
|
|
|
if not os.path.exists(input_path):
|
|
print(f"SKIP: {rel_path} (not found)")
|
|
continue
|
|
|
|
try:
|
|
crop_image(input_path, output_path, crop_amount)
|
|
print(f"OK: {os.path.basename(rel_path)} (cropped {crop_amount}px from top)")
|
|
except Exception as e:
|
|
print(f"FAIL: {rel_path} - {e}")
|
|
|
|
print("\nDone!")
|