Verbessere die Cover-Optimierung durch Anpassung der Größenprüfung und -anpassung für bessere Kompatibilität mit Apple Podcasts.

This commit is contained in:
2025-07-05 20:47:35 +02:00
parent c5abfa342b
commit 6172a898c3
2 changed files with 154 additions and 22 deletions

109
fix_covers.py Normal file
View File

@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""
Cover-Optimierungs-Tool
Repariert alle Cover-Bilder im _audio-Verzeichnis für Apple Podcasts Kompatibilität.
"""
from pathlib import Path
import urllib.parse
def fix_all_covers(audio_dir="../httpdocs/_audio"):
"""Optimiert alle Cover-Dateien im Audio-Verzeichnis."""
try:
from PIL import Image
except ImportError:
print("❌ PIL/Pillow nicht installiert!")
print("💡 Installiere mit: uv add pillow")
return False
audio_path = Path(audio_dir)
if not audio_path.exists():
print(f"❌ Audio-Verzeichnis '{audio_dir}' existiert nicht!")
return False
# Finde alle Cover-Dateien
cover_files = list(audio_path.glob("cover_*.jpg"))
print(f"🖼️ {len(cover_files)} Cover-Dateien gefunden")
if not cover_files:
print(" Keine Cover-Dateien zum Optimieren gefunden")
return True
fixed_count = 0
for cover_file in cover_files:
try:
print(f"\n📋 Prüfe: {cover_file.name}")
# Lade das Bild
image = Image.open(cover_file)
original_width, original_height = image.size
print(f" 📐 Aktuelle Größe: {original_width}x{original_height}px")
# Prüfe ob Optimierung nötig ist
needs_fix = False
if original_width < 1400 or original_height < 1400:
print(f" ⚠️ Zu klein (< 1400px)")
needs_fix = True
elif original_width > 3000 or original_height > 3000:
print(f" ⚠️ Zu groß (> 3000px)")
needs_fix = True
elif original_width != original_height:
print(f" ⚠️ Nicht quadratisch")
needs_fix = True
if not needs_fix:
print(f" ✅ Cover ist bereits optimal")
continue
# Bestimme Zielgröße
if original_width < 1400 or original_height < 1400:
target_size = 1400
elif original_width > 3000 or original_height > 3000:
target_size = 3000
else:
target_size = min(original_width, original_height)
if target_size < 1400:
target_size = 1400
elif target_size > 3000:
target_size = 3000
print(f" 🎯 Zielgröße: {target_size}x{target_size}px")
# Mache quadratisch falls nötig
if original_width != original_height:
size = min(original_width, original_height)
left = (original_width - size) // 2
top = (original_height - size) // 2
right = left + size
bottom = top + size
image = image.crop((left, top, right, bottom))
print(f" ✂️ Zugeschnitten auf quadratisch")
# Skaliere auf Zielgröße
image = image.resize((target_size, target_size), Image.Resampling.LANCZOS)
# Konvertiere zu RGB falls nötig
if image.mode in ('RGBA', 'LA', 'P'):
background = Image.new('RGB', image.size, (255, 255, 255))
if image.mode == 'P':
image = image.convert('RGBA')
background.paste(image, mask=image.split()[-1] if image.mode == 'RGBA' else None)
image = background
# Speichere optimiertes Cover
image.save(cover_file, 'JPEG', quality=95, optimize=True)
final_width, final_height = image.size
print(f" ✅ Optimiert: {final_width}x{final_height}px")
fixed_count += 1
except Exception as e:
print(f" ❌ Fehler bei {cover_file.name}: {e}")
print(f"\n🎉 {fixed_count} von {len(cover_files)} Cover-Dateien optimiert!")
return True
if __name__ == "__main__":
fix_all_covers()