bb7cad9204
Implementiert ein professionelles Build-System für Windows-Benutzer ohne Python-Installation: PyInstaller-Integration: - DocuMentor.spec mit automatischer Icon/Version-Einbindung - Unterstützung für alle PySide6-UI-Dateien und Dependencies - UPX-Kompression für kleinere Executable-Größe Icon-System: - create_icon.py generiert Standard-Icon oder konvertiert PNG zu ICO - Multi-Size ICO (16x16 bis 256x256) für alle Windows-Kontexte - Automatische Integration in Build-Prozess - Prompts für Bild-KIs (Gemini, DALL-E, etc.) Versionsinformationen: - create_version_info.py liest Version aus pyproject.toml - Windows-Datei-Eigenschaften (Rechtsklick → Details) - Automatische Generierung bei jedem Build Build-Automatisierung: - build_windows.py orchestriert gesamten Build-Prozess - Erstellt Icon und Versionsinformationen automatisch - Generiert ZIP-Archiv für Distribution - Cleanup alter Builds Inno Setup-Integration: - installer.iss für professionelle Setup.exe - GUID-Generator (generate_guid.py) - Desktop-Verknüpfungen und Start-Menü-Integration Dokumentation: - BUILD.md - Schnellstart-Anleitung - docs/windows_distribution.md - Detaillierte Distribution-Dokumentation - docs/icon_and_version_info.md - Icon- und Versions-System - resources/icon_prompt.md - KI-Prompts für Icon-Generierung Dependencies: - pyinstaller>=6.0.0 für Executable-Erstellung - pillow>=10.0.0 für Icon-Generierung Externe Abhängigkeiten (Java, FOP, Saxon, diff-pdf) bleiben separat installierbar. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
165 lines
5.2 KiB
Python
165 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Icon-Generator für DocuMentor
|
|
|
|
Erstellt ein Icon aus einem PNG oder generiert ein Standard-Icon.
|
|
Unterstützt Windows (.ico) und verschiedene Größen.
|
|
|
|
Verwendung:
|
|
python create_icon.py # Generiert Standard-Icon
|
|
python create_icon.py source.png # Konvertiert PNG zu ICO
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
except ImportError:
|
|
print("Fehler: Pillow ist nicht installiert.")
|
|
print("Installation: uv pip install pillow")
|
|
sys.exit(1)
|
|
|
|
|
|
def create_default_icon(output_path: Path):
|
|
"""Erstellt ein Standard-Icon mit DocuMentor-Branding."""
|
|
sizes = [256, 128, 64, 48, 32, 16]
|
|
images = []
|
|
|
|
for size in sizes:
|
|
# Neues Bild erstellen mit Farbverlauf
|
|
img = Image.new('RGB', (size, size), color='white')
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Hintergrund: Blau-Verlauf (vereinfacht als solides Blau)
|
|
bg_color = (41, 128, 185) # Professionelles Blau
|
|
draw.rectangle([0, 0, size, size], fill=bg_color)
|
|
|
|
# Dokument-Symbol (vereinfachte Darstellung)
|
|
margin = size // 8
|
|
doc_left = margin
|
|
doc_top = margin
|
|
doc_right = size - margin
|
|
doc_bottom = size - margin
|
|
|
|
# Weißes Dokument
|
|
draw.rectangle(
|
|
[doc_left, doc_top, doc_right, doc_bottom],
|
|
fill='white',
|
|
outline=(52, 73, 94),
|
|
width=max(1, size // 64)
|
|
)
|
|
|
|
# Ecke umgeknickt (rechts oben)
|
|
fold_size = size // 6
|
|
points = [
|
|
(doc_right - fold_size, doc_top),
|
|
(doc_right, doc_top + fold_size),
|
|
(doc_right - fold_size, doc_top + fold_size),
|
|
]
|
|
draw.polygon(points, fill=(220, 220, 220), outline=(52, 73, 94))
|
|
|
|
# Text-Linien im Dokument (nur bei größeren Icons)
|
|
if size >= 32:
|
|
line_margin = doc_left + size // 12
|
|
line_width = doc_right - doc_left - size // 6
|
|
line_count = min(3, size // 32)
|
|
line_spacing = (doc_bottom - doc_top - fold_size) // (line_count + 2)
|
|
|
|
for i in range(line_count):
|
|
y = doc_top + fold_size + line_spacing * (i + 1)
|
|
draw.rectangle(
|
|
[line_margin, y, line_margin + line_width, y + max(1, size // 128)],
|
|
fill=(52, 73, 94)
|
|
)
|
|
|
|
# "M" für Mentor (nur bei großen Icons)
|
|
if size >= 64:
|
|
try:
|
|
# Versuche System-Font zu verwenden
|
|
font_size = size // 4
|
|
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", font_size)
|
|
except:
|
|
# Fallback auf Default-Font
|
|
font = ImageFont.load_default()
|
|
|
|
text = "M"
|
|
# Zentrieren (grobe Schätzung)
|
|
bbox = draw.textbbox((0, 0), text, font=font)
|
|
text_width = bbox[2] - bbox[0]
|
|
text_height = bbox[3] - bbox[1]
|
|
text_x = (size - text_width) // 2
|
|
text_y = doc_bottom - text_height - margin // 2
|
|
|
|
draw.text((text_x, text_y), text, fill=bg_color, font=font)
|
|
|
|
images.append(img)
|
|
|
|
# Als ICO speichern
|
|
images[0].save(
|
|
output_path,
|
|
format='ICO',
|
|
sizes=[(img.width, img.height) for img in images],
|
|
append_images=images[1:]
|
|
)
|
|
print(f"✓ Standard-Icon erstellt: {output_path}")
|
|
|
|
|
|
def convert_png_to_ico(source_path: Path, output_path: Path):
|
|
"""Konvertiert ein PNG-Bild zu einem Multi-Size ICO."""
|
|
try:
|
|
img = Image.open(source_path)
|
|
|
|
# Zu RGBA konvertieren falls nötig
|
|
if img.mode != 'RGBA':
|
|
img = img.convert('RGBA')
|
|
|
|
# Verschiedene Größen erstellen
|
|
sizes = [256, 128, 64, 48, 32, 16]
|
|
images = []
|
|
|
|
for size in sizes:
|
|
resized = img.resize((size, size), Image.Resampling.LANCZOS)
|
|
images.append(resized)
|
|
|
|
# Als ICO speichern
|
|
images[0].save(
|
|
output_path,
|
|
format='ICO',
|
|
sizes=[(img.width, img.height) for img in images],
|
|
append_images=images[1:]
|
|
)
|
|
print(f"✓ Icon erstellt aus {source_path.name}: {output_path}")
|
|
|
|
except Exception as e:
|
|
print(f"✗ Fehler beim Konvertieren: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
def main():
|
|
project_root = Path(__file__).parent
|
|
resources_dir = project_root / "resources"
|
|
resources_dir.mkdir(exist_ok=True)
|
|
|
|
output_ico = resources_dir / "icon.ico"
|
|
|
|
if len(sys.argv) > 1:
|
|
# PNG zu ICO konvertieren
|
|
source_path = Path(sys.argv[1])
|
|
if not source_path.exists():
|
|
print(f"Fehler: Datei nicht gefunden: {source_path}")
|
|
sys.exit(1)
|
|
|
|
convert_png_to_ico(source_path, output_ico)
|
|
else:
|
|
# Standard-Icon generieren
|
|
print("Erstelle Standard-Icon...")
|
|
create_default_icon(output_ico)
|
|
|
|
print(f"\nIcon gespeichert: {output_ico}")
|
|
print("Das Icon wird automatisch von PyInstaller und Inno Setup verwendet.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|