Image Upload Toolkit
approvedby Addo Zhang
Upload local images embedded in Markdown to remote store and export Markdown with image public URL for publishing to static site. Currently, it supports Imgur, Aliyun OSS, ImageKit and AWS S3.
ðļ Obsidian Image Upload Toolkit
Seamlessly upload and manage images for your Obsidian notes across multiple cloud platforms
ð Table of Contents
- ð Quick Start
- âĻ Features
- ð ïļ Installation & Configuration
- ð Usage Guide
- ð§ Storage Service Configuration
- ð Troubleshooting
- ð Best Practices
- ðĨ Contributing
- ð Changelog
- ð Acknowledgements
ð Quick Start
5-Minute Setup
- Install Plugin - Search for "Image Upload Toolkit" in Obsidian Community Plugins
- Basic Configuration - Select Imgur and set up your Client ID
- Start Using - Run the "Publish Page" command in any note
- View Results - Images are automatically uploaded and URLs are copied to clipboard
System Requirements
- Obsidian version âĨ 0.11.0
- Desktop platforms only (Windows/macOS/Linux)
- â ïļ Mobile not supported
âĻ Features
Core Functionality
- â Smart Image Detection - Automatically recognizes Markdown and Wiki link formats
- â Multi-Format Support - PNG, JPG, JPEG, GIF, SVG, WebP, Excalidraw
- â Batch Processing - Upload multiple images simultaneously
- â Real-Time Progress - Optional progress modal with detailed feedback
- â Flexible Paths - Support for relative paths and dynamic path variables
- â Web Image Upload - Download and re-upload web images to your storage (optional)
- â Mermaid Conversion - Automatically convert mermaid diagrams to PNG images during publish (optional)
Supported Storage Services (10 providers)
| Service | Rating | Best For |
|---|---|---|
| Imgur | âââ | Personal blogs |
| GitHub | ââââ | Open source projects |
| Cloudflare R2 | âââââ | Professional use |
| AWS S3 | ââââ | Enterprise |
| Aliyun OSS | ââââ | Chinese users |
| TencentCloud COS | ââââ | Chinese users |
| Qiniu Kodo | ââââ | Chinese users |
| ImageKit | ââââ | CDN optimization |
| Backblaze B2 | ââââ | Cost-effective storage |
| Gyazo | ââââ | Fast sharing workflows |
Perfect for publishing to static sites like GitHub Pages or any platform requiring externally hosted images.
ð ïļ Installation & Configuration
Step 1: Install Plugin
- Open Obsidian Settings â Community Plugins
- Search for "Image Upload Toolkit"
- Click Install and Enable
Step 2: Basic Settings
- Use image name as Alt Text: â Recommended (uses filename as alt text)
- Update original document: â Suggested disabled (preserves original notes)
- Ignore note properties: â Recommended (removes frontmatter when publishing)
- Show progress modal: â Recommended (better user experience)
- Upload web images: â Optional (downloads and re-uploads web images to prevent link rot)
- Convert mermaid diagrams: â Optional (converts mermaid code blocks to PNG images during publish)
- Mermaid scale: 2 (image resolution multiplier, 1-4x)
- Mermaid theme: default (options: default/dark/forest/neutral/base)
Step 3: Choose Storage Service
Select your preferred storage service from the dropdown. See Storage Service Configuration for detailed setup instructions.
ð Usage Guide
Basic Usage
- Open any note with local images
- Use Command Palette (Ctrl/Cmd + P)
- Type "Publish Page" and select the command
- All local images will be uploaded to your configured storage
- Updated markdown with new URLs is copied to clipboard
Advanced Usage
- Custom Paths: Use variables like
{year}/{mon}/{day}/{filename}in path settings - Relative Paths: Support for
./and../relative path formats - Dynamic Attachments: Works with Obsidian's attachment folder settings
- Web Image Upload: Enable in settings to automatically download and re-upload web images (http/https URLs) to your storage service. Images already hosted on your configured storage are automatically skipped.
ð§ Storage Service Configuration
Service Selection Guide
- Personal Use: Imgur (simple and free)
- Open Source: GitHub (version control integration)
- Quick Sharing: Gyazo (simple token-based upload)
- Professional: Cloudflare R2 (high performance)
- Enterprise: AWS S3 (full-featured)
- Chinese Users: Aliyun OSS (optimized for China)
- Budget-Friendly: Backblaze B2 (low-cost with generous free tier)
Detailed Configuration
Imgur (Recommended for Beginners)
1. Visit https://api.imgur.com/oauth2/addclient
2. Create application (select "OAuth 2 authorization without a callback URL")
3. Copy Client ID to plugin settings
4. No additional keys required
GitHub (Recommended for Developers)
1. Create Personal Access Token with 'repo' scope
2. Prepare a public repository for image storage
3. Configure repository information and access token
Note: Images are committed as regular files to the repository
Gyazo
1. Visit https://gyazo.com/oauth/applications
2. Create a Gyazo application
3. Issue an access token from the application dashboard
4. No OAuth callback server is required for this plugin. It uses the issued access token directly.
5. Configure in plugin:
- Access Token
- Access Policy: anyone or only_me
- Common Description: optional shared desc value for every upload
Note: only_me uploads may not be usable for public publishing workflows
Cloudflare R2 (Recommended for Professional Use)
1. Sign up at https://dash.cloudflare.com/sign-up
2. Enable R2 storage in your Cloudflare dashboard
3. Create an R2 bucket for images
4. Generate API credentials:
- Go to R2 â Overview â Manage R2 API Tokens
- Create token with read/write permissions
5. Configure in plugin:
- Access Key ID and Secret Access Key
- Endpoint: https://<account-id>.r2.cloudflarestorage.com
- Bucket Name: Your bucket name
- Custom Domain: Optional (R2.dev URL or custom domain)
AWS S3
1. Create AWS account at https://aws.amazon.com
2. Create S3 bucket with public read access
3. Generate IAM credentials with S3 permissions
4. Configure in plugin:
- Access Key ID and Secret Access Key
- Region: AWS region of your bucket
- Bucket Name: Your S3 bucket name
- Custom Domain: Optional CDN domain
Aliyun OSS (éŋéäšåŊđ蹥ååĻ)
1. Create Alibaba Cloud account
2. Create OSS bucket with appropriate permissions
3. Generate AccessKey pair from RAM console
4. Configure in plugin:
- Access Key ID and Secret
- Region: e.g., oss-cn-hangzhou
- Bucket Name: Your OSS bucket
- Custom Domain: Optional CDN domain
ImageKit
1. Create account at https://imagekit.io/registration/
2. Get API credentials from dashboard
3. Configure in plugin:
- Public Key and Private Key
- URL Endpoint: https://ik.imagekit.io/your_imagekit_id/
- Folder: Optional organization folder
TencentCloud COS (č ūčŪŊäšåŊđ蹥ååĻ)
1. Create Tencent Cloud account
2. Create COS bucket with appropriate permissions
3. Generate SecretId and SecretKey from CAM console
4. Configure in plugin:
- Secret ID and Secret Key
- Region: e.g., ap-guangzhou
- Bucket Name: Your COS bucket
- Custom Domain: Optional CDN domain
Qiniu Kodo (äļįäšååĻ)
1. Create Qiniu Cloud account
2. Create Kodo bucket
3. Generate Access Key and Secret Key
4. Configure in plugin:
- Access Key and Secret Key
- Bucket Name: Your Kodo bucket
- Custom Domain: Domain bound to your bucket
Backblaze B2
1. Create Backblaze account at https://www.backblaze.com/b2/sign-up.html
2. Create a B2 bucket for images
3. Generate Application Key from App Keys page
4. Configure in plugin:
- Key ID: Your application key ID
- Application Key: Your application key
- Bucket ID: Your B2 bucket ID
- Bucket Name: Your B2 bucket name
- Custom Domain: Optional (Cloudflare CDN or custom domain)
ð Troubleshooting
Common Issues
"Cannot locate image" Error
Cause: Incorrect image path configuration or missing files Solution:
- Check Obsidian's attachment folder settings
- Verify image files exist at specified paths
- Try using absolute paths for testing
Imgur Upload Failures
Cause: API limits or network issues Solution:
- Verify Client ID is correct
- Wait a few minutes and retry (Imgur has rate limits)
- Consider alternative storage services
Relative Paths Not Working
Cause: Plugin version or path resolution issues Solution:
- Update to latest version
- Use relative paths starting with
./or../ - Check Obsidian's attachment settings
Progress Modal Not Showing
Cause: Settings issue or plugin conflicts Solution:
- Verify "Show progress modal" setting is enabled
- Restart Obsidian
- Check for conflicting plugins
Upload Errors with Special Characters
Cause: Filename encoding issues Solution:
- Avoid special characters in filenames
- Use only alphanumeric characters, hyphens, and underscores
- Check filename encoding in your file system
Web Image Download Failures
Cause: Network issues, CORS restrictions, or authentication requirements Solution:
- Check your internet connection
- Verify the web image URL is accessible
- Some images may require authentication and cannot be downloaded
- Disable "Upload web images" if you only want to process local images
ð Best Practices
Workflow Recommendations
- Backup Important Data - Always backup before uploading
- Test Configuration - Use test images to verify setup
- Choose Appropriate Storage - Match service to your use case
- Monitor Links - Regularly check uploaded image URLs
Performance Optimization
- Process smaller files first when batch uploading
- Use local storage services when network is unstable
- Regularly clean up unused configuration cache
Security Guidelines
- Never share API keys publicly
- Rotate access credentials regularly
- Use minimum required permissions for storage services
File Organization
- Use consistent naming conventions
- Organize images by date or project
- Consider using path variables for automatic organization
ðĨ Contributing
How to Contribute
- Fork this repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Development Setup
git clone https://github.com/your-username/obsidian-image-upload-toolkit.git
cd obsidian-image-upload-toolkit
npm install
npm run dev
Code Standards
- Use TypeScript strict mode
- Follow existing code style
- Include proper error handling
- Add meaningful commit messages
Testing Requirements
- Test on multiple platforms if possible
- Verify functionality with different storage services
- Ensure backward compatibility
ð Changelog
v1.4.0 (Latest)
- ð Version bump release â same features as v1.3.0 with corrected release tagging
v1.3.0
- âĻ Added mermaid diagram conversion to PNG images during publish
- âĻ Added Backblaze B2 storage support
- âĻ Configurable mermaid scale factor (1-4x) and theme (default/dark/forest/neutral/base)
- ð Fixed double-upload of mermaid-generated images when "Upload web images" is enabled
- ð Mermaid source blocks are preserved when "Update original document" is enabled
- ð§ Migrated ImageKit from SDK to Obsidian's built-in
requestUrlAPI - ð§ Improved B2 MIME type detection and URL derivation
v1.2.0
- âĻ Added web image upload feature (addresses #37)
- âĻ Smart detection to skip images already hosted on your storage
- ð Improved documentation and error messages
v1.1.3
- âĻ Added Cloudflare R2 support
- ð Fixed relative path handling issues
- ð Improved error messages
v1.1.2
- âĻ Added Qiniu Kodo support
- ð Fixed subfolder attachment path issues
- ðĻ Enhanced progress display interface
v1.1.1
- âĻ Added GitHub repository storage support
- ð Fixed dynamic path variable issues
- ð Updated configuration documentation
v1.1.0
- âĻ Added TencentCloud COS support
- ð Fixed various upload issues
- ðĻ Improved user interface
v1.0.0
- ð Initial release
- âĻ Support for Imgur, Aliyun OSS, ImageKit, AWS S3
- ð Basic documentation
ð Acknowledgements
This plugin was inspired by the powerful markdown editor MWeb Pro and builds upon the work of several exceptional projects:
- obsidian-imgur-plugin - Reference implementation for Imgur upload functionality
- obsidian-image-auto-upload-plugin - Inspiration for additional features
- create-obsidian-plugin - Tooling for plugin development
Made with âĪïļ by Addo Zhang
ð Star this repo | ð Report Issues | ð Documentation
Seamlessly upload and manage images for your Obsidian notes across multiple cloud platforms
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.