102 lines
2.5 KiB
Bash
Executable file
102 lines
2.5 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# imgcli.sh — Image processing CLI for OnlyFans profile optimization
|
|
# Usage: ./imgcli.sh input.jpg output.jpg --rotate 180 --crop 1500x500
|
|
|
|
set -e
|
|
|
|
if [ $# -lt 2 ]; then
|
|
echo "Usage: $0 <input_file> <output_file> [--rotate DEGREES] [--crop WIDTHxHEIGHT]"
|
|
echo "Example: $0 onlyfans-header.original.jpg onlyfans-header.jpg --rotate 180 --crop 1500x500"
|
|
exit 1
|
|
fi
|
|
|
|
INPUT="$1"
|
|
OUTPUT="$2"
|
|
ROTATE=0
|
|
CROP_WIDTH=0
|
|
CROP_HEIGHT=0
|
|
|
|
# Parse options
|
|
shift 2
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--rotate)
|
|
ROTATE="$2"
|
|
shift 2
|
|
;;
|
|
--crop)
|
|
IFS='x' read -r CROP_WIDTH CROP_HEIGHT <<< "$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Validate input file
|
|
if [ ! -f "$INPUT" ]; then
|
|
echo "Error: Input file '$INPUT' not found"
|
|
exit 1
|
|
fi
|
|
|
|
# Run Python image processor
|
|
python3 << EOF
|
|
from PIL import Image
|
|
import sys
|
|
|
|
input_file = "$INPUT"
|
|
output_file = "$OUTPUT"
|
|
rotate_angle = $ROTATE
|
|
crop_width = $CROP_WIDTH
|
|
crop_height = $CROP_HEIGHT
|
|
|
|
try:
|
|
img = Image.open(input_file)
|
|
print(f"Loaded: {input_file} ({img.size[0]}x{img.size[1]})")
|
|
|
|
# Step 1: Rotate
|
|
if rotate_angle != 0:
|
|
img = img.rotate(-rotate_angle, expand=True)
|
|
print(f"Rotated {rotate_angle}° → {img.size[0]}x{img.size[1]}")
|
|
|
|
# Step 2: Crop
|
|
if crop_width > 0 and crop_height > 0:
|
|
width, height = img.size
|
|
target_ratio = crop_width / crop_height
|
|
current_ratio = width / height
|
|
|
|
if current_ratio > target_ratio:
|
|
# Too wide, crop width
|
|
new_width = int(height * target_ratio)
|
|
left = (width - new_width) // 2
|
|
top = 0
|
|
right = left + new_width
|
|
bottom = height
|
|
else:
|
|
# Too tall, crop height - bias toward TOP for face
|
|
new_height = int(width / target_ratio)
|
|
left = 0
|
|
top = int(height * 0.1)
|
|
bottom = min(top + new_height, height)
|
|
if bottom == height:
|
|
top = max(0, height - new_height)
|
|
right = width
|
|
|
|
print(f"Crop box: ({left}, {top}, {right}, {bottom})")
|
|
img = img.crop((left, top, right, bottom))
|
|
img = img.resize((crop_width, crop_height), Image.Resampling.LANCZOS)
|
|
print(f"Cropped → {crop_width}x{crop_height}")
|
|
|
|
# Save
|
|
img.save(output_file, quality=95)
|
|
print(f"Saved: {output_file}")
|
|
|
|
except Exception as e:
|
|
print(f"Error: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
EOF
|
|
|
|
echo "✓ Done"
|