feat: Generate thumbnails for article images using Pillow
This commit is contained in:
parent
5c23a13501
commit
257ea3d1a0
|
@ -1,13 +1,84 @@
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
from pelican import signals
|
from pelican import signals
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def generator_finalized(context):
|
THUMBNAIL_MAX_SIZE = 448
|
||||||
for article in context['articles']:
|
|
||||||
pass
|
def generator_finalized(generator):
|
||||||
|
"""
|
||||||
|
Generates thumbnails for images specified in article metadata.
|
||||||
|
"""
|
||||||
|
output_path = generator.settings['OUTPUT_PATH']
|
||||||
|
content_path = generator.settings['PATH']
|
||||||
|
thumb_dir = os.path.join(output_path, 'media', 'thumbs')
|
||||||
|
|
||||||
|
if not os.path.exists(thumb_dir):
|
||||||
|
try:
|
||||||
|
os.makedirs(thumb_dir)
|
||||||
|
log.info(f"Created thumbnail directory: {thumb_dir}")
|
||||||
|
except OSError as e:
|
||||||
|
log.error(f"Could not create thumbnail directory {thumb_dir}: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
for article in generator.articles:
|
||||||
|
if hasattr(article, 'image'):
|
||||||
|
image_path_rel_to_content = article.image
|
||||||
|
# image_path_rel_to_content is often like 'media/imagename.jpg'
|
||||||
|
# or just 'imagename.jpg' if it's directly in 'content/media/'
|
||||||
|
# and STATIC_PATHS includes 'media'.
|
||||||
|
# We assume article.image is a path relative to the 'content' folder.
|
||||||
|
|
||||||
|
source_image_full_path = os.path.join(content_path, image_path_rel_to_content)
|
||||||
|
|
||||||
|
if not os.path.exists(source_image_full_path):
|
||||||
|
log.warning(f"Source image not found for article '{article.slug}': {source_image_full_path}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
image_filename = os.path.basename(image_path_rel_to_content)
|
||||||
|
thumb_path = os.path.join(thumb_dir, image_filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
log.debug(f"Processing image: {source_image_full_path}")
|
||||||
|
img = Image.open(source_image_full_path)
|
||||||
|
|
||||||
|
# Preserve original format, handle potential conversion issues for some modes
|
||||||
|
original_format = img.format
|
||||||
|
if img.mode == 'P' and 'transparency' in img.info: # Palette mode with transparency
|
||||||
|
img = img.convert('RGBA')
|
||||||
|
elif img.mode not in ('RGB', 'RGBA', 'L'): # L is grayscale
|
||||||
|
log.info(f"Converting image {image_filename} from mode {img.mode} to RGB for thumbnailing.")
|
||||||
|
img = img.convert('RGB')
|
||||||
|
|
||||||
|
img.thumbnail((THUMBNAIL_MAX_SIZE, THUMBNAIL_MAX_SIZE))
|
||||||
|
|
||||||
|
save_kwargs = {}
|
||||||
|
if original_format:
|
||||||
|
save_kwargs['format'] = original_format
|
||||||
|
if original_format == 'JPEG':
|
||||||
|
save_kwargs['quality'] = 85 # Adjust quality for JPEGs
|
||||||
|
save_kwargs['optimize'] = True
|
||||||
|
elif original_format == 'PNG':
|
||||||
|
save_kwargs['optimize'] = True
|
||||||
|
|
||||||
|
img.save(thumb_path, **save_kwargs)
|
||||||
|
log.info(f"Generated thumbnail for '{article.slug}': {thumb_path}")
|
||||||
|
|
||||||
|
# Optionally, add thumbnail URL to article metadata if needed by templates
|
||||||
|
# This depends on how SITEURL and paths are structured.
|
||||||
|
# For now, just creating the file.
|
||||||
|
# article.thumbnail_url = f"{generator.settings.get('SITEURL', '')}/media/thumbs/{image_filename}"
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
log.error(f"Image file not found: {source_image_full_path}")
|
||||||
|
except IOError as e:
|
||||||
|
log.error(f"Could not open or process image {source_image_full_path}: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
log.error(f"An unexpected error occurred while processing {source_image_full_path}: {e}")
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|
Loading…
Reference in New Issue
Block a user