Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Obsidian Image Localizer

📖 Documentation: English · 中文

A small, dependency-free Python CLI that downloads remote images referenced in your Obsidian Markdown notes (e.g. saved via the Obsidian Web Clipper) into local attachments/ folders, and rewrites the links to relative paths — so your notes work fully offline.

  • Local / already-offline images: left untouched.
  • Already-localized images: not re-downloaded on re-run (idempotent).
  • Downloads + rewrites only — never deletes your files.
  • Links inside code blocks / inline code are ignored, so documented examples are not mistaken for real images.

Requirements

Item Requirement
OS macOS / Windows / Linux
Python 3.6+ (3.8+ recommended)
Dependencies None — standard library only, no pip install
Network Must be able to reach the image URLs

Setup

macOS / Linux — Python 3 is usually preinstalled. Verify:

python3 --version

Windows — Download from python.org; tick "Add Python to PATH" during install. Then:

python --version

⚠️ On Windows the command is python, not python3.


Usage

# macOS / Linux
python3 localize_images.py
# Windows
python localize_images.py

By default it processes the current directory (and all sub-directories).

Process a specific directory:

python3 localize_images.py /path/to/your/vault

Options

Option Description
root Root directory to scan (default: current directory)
--dry-run Preview only — list what would be downloaded, change nothing
--workers N Concurrent downloads (default 8; raise to 16 for many images)
--no-rewrite Download only, don't rewrite the markdown (debug)
--referer URL Custom Referer header to bypass hotlink protection
--exclude PATH Exclude a file or folder (incl. subfolders); repeatable; also reads .imagelocalizerignore

Excluding files / folders

Skip notes you don't want touched — e.g. a folder of private notes, or one specific file. Folders are skipped entirely, including their subfolders:

python3 localize_images.py --exclude 010Finance/SeekingAlpha --exclude "Private Notes.md"

You can also drop a .imagelocalizerignore file (gitignore-style, # comments) in the root; each line is a path to exclude. Excluded folders (and their subfolders) are skipped as a whole. A ready-to-edit template lives at .imagelocalizerignore.example — copy it to .imagelocalizerignore and adjust the rules.


Recommended workflow

  1. Preview first (safe, changes nothing):
    python3 localize_images.py --dry-run
  2. Run for real (downloads + rewrites links):
    python3 localize_images.py
  3. Open Obsidian and confirm images render.

How it works

  1. Walks the root directory for every .md file (excluded items are skipped entirely).
  2. Parses image links from three sources — after stripping code blocks and inline code so examples aren't mistaken for real images:
    • Standard Markdown: ![alt](https://image-url.png)
    • HTML tags: <img src="https://...">
    • Inline base64: data:image/png;base64,...
  3. Downloads http/https and data: images into the note's sibling attachments/ folder; an MD5 hash is appended to the filename to avoid collisions.
  4. Rewrites each link to the relative attachments/name.png path.
  5. Failed downloads retry 3×; still-failing ones are skipped with a warning.

Notes / FAQ

  • Always --dry-run first.
  • Revert anytime: if your vault is Git-tracked (Obsidian Git), just git checkout.
  • Hotlink 403: some CDNs block requests without a referer — re-run with --referer https://www.douban.com/ (or the source site).
  • 404 dead link: the source URL itself is broken/invalid — the script can't fix it; manually correct or delete that image line.
  • Idempotent: after the first run links become local, so a second run finds nothing.
  • Chinese paths / filenames: fully supported (Python 3 native Unicode).
  • Where do images go? Into an attachments/ folder next to each note (relative paths, which Obsidian resolves on every platform).

Troubleshooting

Symptom Cause Fix
'python3' is not recognized (Windows) PATH not set / used python3 Use python; re-install with "Add to PATH"
Many IncompleteRead Unstable network / rate limit Auto-retried; re-run later if needed
HTTP 403 Hotlink protection Re-run with --referer
HTTP 404 Source link dead Fix the URL or delete the image line
Images downloaded but not shown Links not rewritten Don't use --no-rewrite; run again

License

MIT © 2026 stevenlii

About

Python CLI to download remote images in Obsidian Markdown notes into local attachments.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages