← back to Resize It
scripts/analyze_proportions.py
116 lines
#!/usr/bin/env python3
"""
AI-powered image proportion analysis
Analyzes images to detect distortion or incorrect proportions
"""
import sys
import json
import base64
import argparse
from pathlib import Path
def encode_image_to_base64(image_path):
"""Encode image to base64 for API transmission"""
with open(image_path, 'rb') as img_file:
return base64.b64encode(img_file.read()).decode('utf-8')
def get_image_mime_type(image_path):
"""Determine MIME type from file extension"""
suffix = Path(image_path).suffix.lower()
mime_types = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.webp': 'image/webp',
'.bmp': 'image/bmp'
}
return mime_types.get(suffix, 'image/jpeg')
def analyze_image_proportions_prompt(original_path=None, resized_path=None):
"""
Generate analysis prompt for Claude/Gemini to analyze image proportions
Returns:
dict with prompt and image data for API call
"""
analysis_request = {
"task": "image_proportion_analysis",
"instruction": """Analyze the provided image(s) for proportion and distortion issues.
Please examine:
1. **Aspect Ratio**: Are objects in the image proportioned correctly? Do circles look like circles, squares like squares?
2. **Distortion**: Is there any stretching, squashing, or warping visible?
3. **Expected Proportions**: Do people, objects, or text appear at natural proportions?
4. **Comparison** (if two images provided): How does the resized image compare to the original? Is there any introduced distortion?
Provide your analysis in JSON format with these fields:
{
"has_distortion": boolean,
"distortion_type": "horizontal_stretch" | "vertical_stretch" | "horizontal_squash" | "vertical_squash" | "none" | "unknown",
"severity": "none" | "minor" | "moderate" | "severe",
"confidence": float (0-1),
"observations": [list of specific observations],
"recommendation": "string with recommended action"
}
Be thorough but objective in your analysis."""
}
images = []
if original_path:
images.append({
"label": "original",
"path": original_path,
"base64": encode_image_to_base64(original_path),
"mime_type": get_image_mime_type(original_path)
})
if resized_path:
images.append({
"label": "resized",
"path": resized_path,
"base64": encode_image_to_base64(resized_path),
"mime_type": get_image_mime_type(resized_path)
})
analysis_request["images"] = images
return analysis_request
def main():
parser = argparse.ArgumentParser(
description='Prepare image proportion analysis for AI (Claude/Gemini)'
)
parser.add_argument('--original', help='Original image path')
parser.add_argument('--resized', help='Resized image path')
parser.add_argument('--output-format', choices=['json', 'prompt'], default='json',
help='Output format: json (full data) or prompt (text prompt only)')
args = parser.parse_args()
if not args.original and not args.resized:
print("Error: Must provide at least one image (--original or --resized)")
sys.exit(1)
# Generate analysis request
analysis_data = analyze_image_proportions_prompt(args.original, args.resized)
if args.output_format == 'json':
# Output full JSON (includes base64 encoded images)
print(json.dumps(analysis_data, indent=2))
else:
# Output just the prompt text
print(analysis_data["instruction"])
if __name__ == '__main__':
main()