ObsiGate/CHANGELOG_IMAGE_RENDERING.md

6.6 KiB

Changelog - Obsidian Image Rendering Feature

Version 1.2.0 - Image Rendering Support

🖼️ New Features

Comprehensive Image Syntax Support

  • Standard Markdown with HTML attributes: [<img width="180" height="60" src="path"/>](url)
  • Obsidian wiki-link embeds (full path): ![[folder/subfolder/image.svg]]
  • Obsidian wiki-link embeds (filename only): ![[image.png]]
  • Standard Markdown images: ![alt](path/to/image.png)

Intelligent Multi-Strategy Path Resolution

Implements 7-tier resolution system with priority order:

  1. Absolute path detection
  2. Configured attachments folder lookup
  3. Startup index unique match
  4. Same directory as markdown file
  5. Vault root relative resolution
  6. Startup index closest path match
  7. Styled placeholder fallback

Attachment Indexing System

  • Asynchronous vault scanning at startup
  • Supports: .png, .jpg, .jpeg, .gif, .svg, .webp, .bmp, .ico
  • Per-vault index with filename → absolute path mapping
  • Resolution cache for performance optimization
  • Detailed logging of indexed attachments

Vault Configuration Extensions

New optional environment variables:

  • VAULT_N_ATTACHMENTS_PATH: Relative path to primary attachments folder
  • VAULT_N_SCAN_ATTACHMENTS: Enable/disable attachment scanning (default: true)

API Endpoints

  • GET /api/image/{vault}?path=...: Serve images with proper MIME types
  • POST /api/attachments/rescan/{vault}: Manual vault attachment rescan
  • GET /api/attachments/stats?vault=...: Attachment statistics per vault

Frontend Enhancements

  • Responsive image rendering with max-width constraints
  • Styled placeholders for missing images with tooltips
  • Hover effects on linked images
  • Rounded corners and subtle shadows

📁 New Files

  • backend/attachment_indexer.py: Image scanning, indexing, and resolution
  • backend/image_processor.py: Markdown preprocessing for all image syntaxes
  • IMAGE_RENDERING_GUIDE.md: Comprehensive implementation and testing guide
  • CHANGELOG_IMAGE_RENDERING.md: This file

🔧 Modified Files

Backend

  • backend/indexer.py:

    • Updated vault config to support attachments configuration
    • Integrated attachment index building at startup
    • Added config storage in vault data structure
  • backend/main.py:

    • Added image preprocessing to markdown rendering pipeline
    • Implemented /api/image/{vault} endpoint with MIME type detection
    • Added /api/attachments/rescan/{vault} endpoint
    • Added /api/attachments/stats endpoint
    • Updated _render_markdown() to accept current file path
    • Imported mimetypes module for content-type detection

Frontend

  • frontend/style.css:
    • Added .image-not-found placeholder styling
    • Added responsive image rendering styles
    • Added hover effects for linked images

Documentation

  • README.md:
    • Added image rendering feature to features list
    • Added new environment variables documentation
    • Added new API endpoints to API section
    • Added comprehensive "Rendu d'images Obsidian" section
    • Updated usage instructions

🎯 Implementation Details

Resolution Algorithm

def resolve_image_path(image_src, vault_name, vault_root, current_file_path, attachments_path):
    # 1. Check cache
    # 2. Try absolute path
    # 3. Try config attachments folder
    # 4. Try startup index (unique match)
    # 5. Try same directory as markdown file
    # 6. Try vault root relative
    # 7. Try startup index (closest match)
    # 8. Return None (fallback to placeholder)

Image Preprocessing Pipeline

def preprocess_images(content, vault_name, vault_root, current_file_path, attachments_path):
    # 1. Process HTML img in markdown links
    # 2. Process wiki-link embeds
    # 3. Process standard markdown images
    # All paths resolved and transformed to /api/image endpoint

Attachment Index Structure

attachment_index = {
    "VaultName": {
        "image.png": [Path("/absolute/path/to/image.png")],
        "logo.svg": [Path("/path/1/logo.svg"), Path("/path/2/logo.svg")]
    }
}

🔒 Security

  • Path traversal protection maintained for image serving
  • All image paths validated through _resolve_safe_path()
  • MIME type detection prevents serving arbitrary files
  • Read-only vault mounts recommended in docker-compose

Performance

  • Startup: O(n) scan where n = number of files in vault
  • Resolution (cached): O(1) hash table lookup
  • Resolution (uncached): O(k) where k ≤ 7 strategies
  • Memory: ~100 bytes per indexed image
  • Cache invalidation: On manual rescan only

📊 Logging

New log messages:

  • Vault '{name}': indexed {count} attachments (INFO)
  • Vault '{name}': attachment scanning disabled (INFO)
  • Image resolved via strategy N (description) (DEBUG)
  • Image not resolved (fallback) (DEBUG)
  • Rescanned attachments for vault '{name}': {count} attachments (INFO)

🧪 Testing

All acceptance criteria met:

  • All 4 image syntaxes render correctly
  • Startup scan is asynchronous and non-blocking
  • Filename-only wiki-links resolve via index
  • Config attachmentsPath used as priority
  • Unresolved images show styled placeholder
  • No regression on standard markdown syntax
  • Rescan command works without restart

🐛 Known Limitations

  1. No automatic file watching: Changes to image files require manual rescan
  2. No thumbnail generation: Large images served at full resolution
  3. No image optimization: Images served as-is from filesystem
  4. Case sensitivity: Filename matching is case-insensitive, but path matching respects OS

🔄 Migration Guide

For Existing Installations

  1. No breaking changes: Feature is fully backward compatible
  2. Optional configuration: Works without any new environment variables
  3. Automatic indexing: Enabled by default for all vaults

To Enable Optimized Resolution

Add to your docker-compose.yml:

environment:
  - VAULT_1_ATTACHMENTS_PATH=Assets/Images  # Your attachments folder

To Disable Scanning (for vaults without images)

environment:
  - VAULT_N_SCAN_ATTACHMENTS=false

📝 Documentation

  • README.md: Updated with feature overview and configuration
  • IMAGE_RENDERING_GUIDE.md: Comprehensive implementation guide
  • CHANGELOG_IMAGE_RENDERING.md: This detailed changelog

🙏 Acknowledgments

Implementation based on Obsidian's image handling specifications and community feedback regarding vault attachment organization patterns.


Release Date: 2025
Compatibility: ObsiGate 1.1.0+
Python Version: 3.11+
Dependencies: No new dependencies required