Files
dealplustech/crop_banners.py
2026-02-25 22:04:30 +07:00

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!")