> See shared-standards.md for common technical constraints. # SVG Image Embedding Guide Technical spec and workflow for adding images to SVG files. --- ## Image Resource List Format Defined in the Design Specification & Content Outline; each image carries an `Acquire Via` field plus a status annotation. This file is authoritative for status names and SVG embedding behavior. If image approach includes "B) User-provided": run `analyze_images.py` right after the Eight Confirmations and complete the list before outputting the design spec. ```markdown | Filename | Dimensions | Purpose | Type | Acquire Via | Status | Reference | |----------|------------|---------|------|-------------|--------|-----------| | cover_bg.png | 1280x720 | Cover background | Background | ai | Pending | Modern tech abstract, deep blue gradient | | team.jpg | 800x600 | Team photo | Photography | web | Pending | Diverse engineering team in modern office | | product.png | 600x400 | Page 3 product photo | Photography | user | Existing | - | | formula_001.png | 736x168 | Page 3 block equation | Latex Formula | formula | Rendered | `E = mc^2` | | chart.png | 600x400 | Page 5 placeholder | Illustration | placeholder | Placeholder | Team collaboration scene to be added later | ``` ### Image Status Enum | Status | Meaning | Executor Handling | |--------|---------|-------------------| | **Pending** | Acquisition needed (`Acquire Via: ai` or `web`); not yet attempted | Image Acquisition Phase (Step 5) consumes this; must not remain after Step 5 | | **Generated** | AI-generated file exists at expected path | Reference from `../images/`; no on-slide credit needed | | **Sourced** | Web-sourced file exists at expected path | Reference from `../images/`; check `image_sources.json` for `license_tier` — if `attribution-required`, render an inline credit element on the slide (see [executor-base.md §6](./executor-base.md) and [image-searcher.md §7](./image-searcher.md) for the visual spec) | | **Rendered** | Deterministic formula PNG exists at expected path (`Acquire Via: formula`) | Reference from `../images/`; use `preserveAspectRatio="xMidYMid meet"` and do not crop | | **Needs-Manual** | Acquisition attempted once + one retry, failed | Dashed placeholder unless user has manually supplied the file | | **Existing** | User already has image (`Acquire Via: user`) | Place in `images/`, reference with `` | | **Placeholder** | Intentionally not prepared yet (`Acquire Via: placeholder`) | Dashed border placeholder; replace later | --- ## Workflow ``` 1. Strategist defines image needs → Add image resource list with Acquire Via + Status per row 2. Image Acquisition (Step 5): - Pending + ai → Image_Generator runs image_gen.py → Generated - Pending + web → Image_Searcher runs image_search.py → Sourced - formula / user / placeholder rows are skipped 3. Executor generates SVGs (svg_output/) ├── Existing / Generated → ├── Sourced + license_tier=no-attribution → only ├── Sourced + license_tier=attribution-required → + small credit element on the slide ├── Rendered formula → └── Placeholder / Needs-Manual without file → Dashed border + description text 4. Preview: python3 -m http.server -d 8000 → /svg_output/.svg 5. Post-processing & Export → follow shared-standards.md §5 ``` > Keep external references in `svg_output/` during generation. `finalize_svg.py` auto-embeds images into `svg_final/`; export PPTX from `svg_final/`. --- ## External Reference vs Base64 Embedding | Method | Pros | Cons | Suitable For | |--------|------|------|-------------| | **External reference** | Small file size, fast iteration, easy to replace | Preview requires HTTP server from project root | `svg_output/` development phase | | **Base64 embedding** | Self-contained file, stable export | Large file size | `svg_final/` delivery phase | --- ## Method 1: External Reference (Recommended for Generation Phase) ### Syntax ```xml ``` ### Key Attributes | Attribute | Description | Example | |-----------|-------------|---------| | `href` | Image path (relative or absolute) | `"../images/cover.png"` | | `x`, `y` | Image top-left corner position | `x="0" y="0"` | | `width`, `height` | Image display dimensions | `width="1280" height="720"` | | `preserveAspectRatio` | Scaling mode | `"xMidYMid slice"` | ### preserveAspectRatio Common Values | Value | Effect | |-------|--------| | `xMidYMid slice` | Center crop (similar to CSS `cover`) | | `xMidYMid meet` | Complete display (similar to CSS `contain`) | | `none` | Stretch to fill, no aspect ratio preservation | ### Preview Method Browser security blocks external images on directly opened SVGs. Serve via HTTP from the project root: ```bash python3 -m http.server -d 8000 # Visit http://localhost:8000/svg_output/your_file.svg ``` --- ## Method 2: Base64 Embedding (Recommended for Delivery Phase) ### Syntax ```xml ``` ### MIME Types | MIME Type | File Format | |-----------|-------------| | `image/png` | PNG | | `image/jpeg` | JPG/JPEG | | `image/gif` | GIF | | `image/webp` | WebP | | `image/svg+xml` | SVG | --- ## Conversion Process Use the unified pipeline in [shared-standards.md §5](shared-standards.md). `finalize_svg.py` runs before export so image references in `svg_output/` become embedded assets in `svg_final/`. ```bash python3 scripts/finalize_svg.py python3 scripts/svg_to_pptx.py ``` ### Standalone: embed_images.py (advanced) For processing specific SVGs without the full pipeline: ```bash python3 scripts/svg_finalize/embed_images.py # Single file python3 scripts/svg_finalize/embed_images.py /svg_output/*.svg # Batch python3 scripts/svg_finalize/embed_images.py --dry-run /svg_output/*.svg # Preview ``` --- ## Best Practices ### Image Optimization Compress before embedding to reduce file size: ```bash convert input.png -quality 85 -resize 1920x1080\> output.png # ImageMagick pngquant --quality=65-80 input.png -o output.png # pngquant (recommended) ``` ### File Organization ``` project/ ├── images/ # Image assets ├── sources/ # Source files and their accompanying images │ └── article_files/ ├── svg_output/ # Raw version (external references) └── svg_final/ # Final version (images embedded) ``` ### Rounded Corner / Non-rectangular Image Cropping `clipPath` **on `` elements** is conditionally allowed — authoritative constraints in [shared-standards.md §1.2](shared-standards.md); do not restate or relax here. Fallback when `clipPath` doesn't fit: bake rounded corners into the source image (PNG with alpha) before embedding. --- ## FAQ **Q: Can't see images when opening SVG directly?** Browser security blocks cross-directory requests. Serve via HTTP from project root, or run `finalize_svg.py` first and view from `svg_final/`. **Q: Base64 file too large?** Compress the source, use JPEG, reduce resolution to match actual display dimensions. **Q: How to reverse-extract a Base64 image?** ```bash base64 -d image.b64 > image.png ```