mdimg_localizer: Automatic Markdown Image Downloader & Link Updater
mdimg_localizer is a Python utility for automatically downloading remote images referenced in your Markdown (.md
) files and updating the image links to local paths. It is designed for static site/blog repositories (such as Jekyll or Hugo) where you want to keep all images under version control and avoid hotlinking.
🚀 Features
- Scans Markdown files for remote image URLs (e.g.,

) - Downloads each image into a dedicated folder under
/assets/img/posts/<post-name>/
- Renames images to use only ASCII characters (a-z, A-Z, 0-9, -, _)
- Updates the Markdown files to reference the new local image paths
- Skips badge/shield images and already-local images
- Works on a single file or all files in the
_posts/
directory - Logs all actions and errors to
image_downloader.log
✨ Highlights
✅ Download all remote images in your Markdown posts
✅ Automatically create per-post image folders
✅ Cleans image filenames (removes non-ASCII and special characters)
✅ Updates Markdown files with new local image paths
✅ Skips common badge/shield services
✅ Works on a single file or all files in _posts/
📂 Directory Structure
1
2
3
4
5
6
7
8
9
10
repo-root/
├── _posts/
│ └── your-posts.md
├── assets/
│ └── img/
│ └── posts/
│ └── <post-name>/
│ └── downloaded-images.jpg
├── mdimg_localizer.py
└── README.md
🔧 Requirements
- Python 3.6+
- requests library
Install with:1
pip install requests
⚙️ Installation
- Place
mdimg_localizer.py
in your repository (e.g., in atools/
folder). - Install dependencies:
1
pip install requests
📝 Usage
1
python mdimg_localizer.py [markdown_file.md]
- If no file is specified, all
.md
files in the_posts/
directory will be processed.
🛡️ Skipped Services
The script automatically skips images from common badge/shield services, such as:
img.shields.io
visitor-badge.laobi.icu
www.gnu.org/graphics
shields.io
⚖️ License
This project is licensed under the GNU General Public License v3.0 (GPL-3.0).
See the LICENSE file for details.
🛠️ How It Works (Technical Details)
- Image Detection: Uses regular expressions to find all remote image links in Markdown files.
- Download & Save: Downloads each image and saves it in a dedicated folder named after the Markdown file (without extension) under
assets/img/posts/
. - Filename Cleaning: Filenames are normalized to ASCII, removing accents and special characters, and only allowing a-z, A-Z, 0-9,
-
, and_
. - Link Update: The Markdown file is updated to reference the new local image path.
- Duplicate Handling: If multiple images would have the same filename, a unique hash and index are appended.
- Logging: All actions and errors are logged for traceability.
🤔 Why Use mdimg_localizer?
Keeping all images local in your Markdown posts ensures your content remains accessible, reliable, and under your control. By avoiding hotlinked images, you prevent broken links, speed up site loading, and maintain a consistent look for your blog or documentation.
🌟 Example Workflow
Let’s see how mdimg_localizer works in practice:
- Original Markdown:
1 2
 
- Run the tool:
1
python mdimg_localizer.py _posts/my-post.md
- Resulting Markdown:
1 2
 
- Remote images are downloaded and linked locally.
- Badge images are skipped automatically.
About
Author: fr0stb1rd
Repo: gitlab/fr0stb1rd/mdimg-localizer
Blog Post: fr0stb1rd.gitlab.io
License: GPL-3.0
SPDX-License-Identifier: GPL-3.0