#!/usr/bin/env python # -*- coding: utf-8 -*- # # 画像からblurhashとshortcodeを生成する # Generate blurhash and shortcode from images import os import json import sys import argparse from PIL import Image def generate_blurhash(image_path): """Generate a blurhash for an image using external blurhash command.""" try: import subprocess subprocess.run(['blurhash', image_path], capture_output=True, text=True, check=True) except subprocess.CalledProcessError as e: raise Exception(f"Failed to generate blurhash: {e.stderr}") def get_image_info(image_path): """Get image dimensions and generate blurhash if needed.""" with Image.open(image_path) as img: width, height = img.size return width, height def process_image(image_path, base_dir, url_base): """Process a single image file.""" try: width, height = get_image_info(image_path) # Setup paths base_name, ext = os.path.splitext(os.path.basename(image_path)) directory = os.path.dirname(image_path) blurhash_file = os.path.join(directory, f"{base_name}{ext}.bh") caption_file = os.path.join(directory, f"{base_name}.caption") # Generate or read blurhash if not os.path.exists(blurhash_file): print(f"Generating blurhash for: {image_path}") generate_blurhash(image_path) with open(blurhash_file, 'r') as bh_file: blurhash = bh_file.read().strip() else: with open(blurhash_file, 'r') as bh_file: blurhash = bh_file.read().strip() # Read caption if exists caption = "" if os.path.exists(caption_file): with open(caption_file, 'r') as cap_file: caption = cap_file.read().strip() # Generate shortcode filename = os.path.basename(image_path) directory_rel = os.path.relpath(directory, base_dir) if directory_rel == '.': directory_rel = "" # Remove './' by setting to empty string else: directory_rel = directory_rel.replace('static/', '', 1) if directory_rel: src_path = f"{url_base.rstrip('/')}/{directory_rel}/{filename}" if url_base else f"{directory_rel}/{filename}" else: src_path = f"{url_base.rstrip('/')}/{filename}" if url_base else f"{filename}" # Create the shortcode content shortcode_content = f"""{{{{< blurhash src="{src_path}" blurhash="{blurhash}" width="{width}" height="{height}" alt="{caption}" grid="true" >}}}}""" # Write the shortcode file cringe_filename = f"{filename}.cringe" output_path = os.path.join(directory, cringe_filename) with open(output_path, 'w') as cringe_file: cringe_file.write(shortcode_content) print(f"Processed: {image_path}") except Exception as e: print(f"Error processing {image_path}: {str(e)}") def recurse_directories(base_dir, url_base): """Recursively process all images in directory.""" for root, _, files in os.walk(base_dir): for file in files: if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')): image_path = os.path.join(root, file) process_image(image_path, base_dir, url_base) def parse_args(): parser = argparse.ArgumentParser(description='Generate blurhash and shortcode from images') parser.add_argument('directory', nargs='?', default=os.getcwd(), help='Directory to process (default: current directory)') parser.add_argument('--url', '-u', default='', help='Base URL for src attribute (e.g., https://example.com)') return parser.parse_args() if __name__ == "__main__": args = parse_args() # Check if directory exists if not os.path.isdir(args.directory): print(f"Error: Directory '{args.directory}' does not exist") sys.exit(1) print(f"Processing directory: {args.directory}") print(f"Using URL base: {args.url if args.url else '(none)'}") recurse_directories(args.directory, args.url)