imulan620 downloadsA powerful image management plugin for Obsidian. Browse, optimize, upload to image hosting, and organize your images. Ideal for converting Wiki image refs to standard Markdown format.
English | 中文
Obsidian image management plugin — supports image compression, image hosting upload, reference format conversion, local and remote image browsing, and more.
Note: This plugin is primarily designed for vaults that use standard Markdown format (
) for image references.When "Use Markdown standard format" is enabled, features like paste image, organize resources, and image hosting upload all work based on standard Markdown format. The plugin supports batch converting Wiki format (
![[image.png]]) to standard Markdown format, but does not support reverse conversion.
Found a bug or have an idea? Open a GitHub issue so it can be tracked and discussed.
To help diagnose problems quickly, include:
For private questions, contact [email protected]. If you find the plugin useful, consider giving the project a ⭐.
| Feature | Status |
|---|---|
| Image Browser (Local and Hosting Images) | ✅ Implemented |
| Local Reference Status Filter and Guarded Orphan Cleanup | ✅ Implemented |
| Image Compression (Canvas API) | ✅ Implemented |
| Wiki → Markdown Reference Conversion | ✅ Implemented |
| Markdown → Wiki Reference Conversion | ❌ Not Supported |
| Image Hosting Upload (Aliyun OSS / Qiniu / S3 / Custom) | ✅ Implemented |
| Aliyun OSS / S3 / Qiniu Card Browser, Viewport Thumbnails, and Preview | ✅ Implemented |
| Custom Upload Reference Template | ✅ Implemented |
| Auto Upload on Paste | ✅ Implemented |
| Batch Upload Note Images | ✅ Implemented |
| Batch Upload Entire Vault | ✅ Implemented |
| Orphan Image Detection & Cleanup | ✅ Implemented |
| Image Rename (sync update all references) | ✅ Implemented |
| Image Resource Organization (archive by template path) | ✅ Implemented |
| Paste/Drag & Drop Image Auto Processing | ✅ Implemented |
| Right-click Menu Integration | ✅ Implemented |
| Chinese/English Internationalization | ✅ Implemented |
| Image Hosting Migration | ❌ Not Implemented |
| Replace Hosting References with Local | ❌ Not Implemented |
| Item | Technology |
|---|---|
| Language | TypeScript 5.8 (strict mode) |
| Runtime | Obsidian Plugin API |
| Bundler | esbuild → CommonJS main.js |
| Encryption | Web Crypto API (crypto.subtle) |
| HTTP | Obsidian requestUrl |
| i18n | Custom i18n (Chinese/English) |
| Lint | ESLint + typescript-eslint + obsidianmd plugin |
| CI | GitHub Actions (Node 22.x) |
Zero bundled runtime dependencies — npm packages are used only for development, type checking, testing, and building.
.obsidian/plugins/md-image-manager/# Install dependencies
npm install
# Development mode (watch)
npm run dev
# Production build
npm run build
# Lint
npm run lint
# Automated tests
npm test
# Version update (choose the appropriate SemVer level)
npm version patch
# npm version minor
# npm version major
Build artifacts: main.js, manifest.json, styles.css
src/
├── main.ts # Plugin entry, command registration, event handling, core orchestration
├── settings.ts # Settings panel UI
├── types.ts # TypeScript type definitions and defaults
├── constants.ts # Regular expressions, MIME type mappings
├── i18n/
│ ├── index.ts # Internationalization system (locale switching, variable interpolation)
│ ├── en.ts # English translations (300+ entries)
│ └── zh.ts # Chinese translations (300+ entries)
├── modals/
│ ├── image-browser.ts # Local/remote image browser shell
│ ├── remote-image-browser.ts # Remote scan orchestration and safety gates
│ ├── remote-image-grid.ts # Progressive card grid and viewport thumbnails
│ ├── remote-image-preview.ts # Remote preview and reference locations
│ ├── remote-folder-picker.ts # Provider virtual-folder picker
│ ├── remote-delete-confirm.ts # Guarded remote delete confirmation
│ ├── remote-delete-results.ts # Per-object delete results
│ ├── image-preview-modal.ts # Image preview (metadata, reference list, upload actions)
│ ├── orphan-images.ts # Orphan image detection and batch deletion
│ ├── hosting-config.ts # Image hosting config form (4 providers)
│ ├── confirm-dialog.ts # Generic confirmation dialog
│ ├── rename-image.ts # Image rename dialog
│ └── image-name-prompt.ts # Image naming prompt on paste
├── uploaders/
│ ├── uploader-base.ts # Uploader abstract base class
│ ├── uploader-factory.ts # Uploader factory (instantiate by type)
│ ├── upload-service.ts # Unified direct, note, batch, and paste upload orchestration
│ ├── aliyun-oss.ts # Aliyun OSS (OSS V4 signing)
│ ├── qiniu.ts # Qiniu Cloud (Token auth, region endpoints)
│ ├── s3-compatible.ts # S3 compatible storage (AWS SigV4)
│ ├── public-url.ts # Public URL base normalization and joining
│ ├── custom-uploader.ts # Custom HTTP endpoint
│ └── upload-queue.ts # Concurrent upload queue (3 concurrent, 3 retries, progress callback)
├── remote/ # Provider-independent remote sessions, safety policies, and native providers
├── oss/
│ └── sigv4.ts # Shared OSS upload/list/preview/delete signing
├── qiniu/
│ └── auth.ts # Upload, management, and private-preview authentication
├── s3/
│ └── sigv4.ts # Shared S3 upload/list/preview/delete signing
└── utils/
├── ref-converter.ts # Reference format parsing and conversion
├── reference-template.ts # Uploaded reference template validation and rendering
├── image-scanner.ts # Image scanning, filtering, sorting
├── local-orphan-management.ts # Fresh local orphan validation and trash
├── path-utils.ts # Path utilities, file size formatting, template variables
├── public-url.ts # Markdown-safe Unicode URL display
├── orphan-finder.ts # Orphan image detection, reverse reference query
├── image-optimizer.ts # Canvas compression, format conversion
├── batch-rename.ts # Batch rename (sync update all vault references)
└── image-reorganizer.ts # Image archive organization (path template, reference update)
{noteName} — Current note name{notePath} — Current note path{year}, {month}, {day} — Date{filename} — Image filename format, disable to use ![[path]] Wiki format (image hosting requires this to be enabled)
Settings Combination Behavior:
| Use MD Standard | Skip Wiki Refs | Paste Format | Organize Behavior |
|---|---|---|---|
| ✅ Enabled | ✅ Enabled |  |
Skip Wiki refs, only organize MD format images |
| ✅ Enabled | ❌ Disabled |  |
Convert Wiki refs to MD format and organize (one-way) |
| ❌ Disabled | ✅ Enabled | ![[path]] |
Skip Wiki refs, only organize MD format images |
| ❌ Disabled | ❌ Disabled | ![[path]] |
Organize all format images (preserve original format) |
Note: Wiki → Markdown conversion is one-way and cannot be automatically reversed.
{noteName}, {date}, {time}, {timestamp}, {counter}, {year}, {month}, {day}


Note: Image hosting requires "Use Markdown Standard Format" to be enabled.
{year}, {month}, {day}, {filename}, {ext}, {hash}, {timestamp}, {sourceDir}{fileUrl} is required and file metadata or intrinsic dimensions can be included

Aliyun OSS, S3-compatible, and Qiniu remote browsing list objects only after an explicit scan, with a visible loading state for longer scans. Results use an image card grid, and thumbnails load automatically as they approach the viewport; this can incur object-read, original-file transfer, and provider charges. Reference scanning covers Markdown images, plain links, HTML, frontmatter, Wiki wrappers, and raw URLs; every reliably mapped address counts as a reference. Select an image to view its referencing notes and line numbers and jump directly to the source. Objects with no detected reference are labeled "Orphan image" and can be selected for deletion. This does not prove that websites, other vaults, or other applications do not use the object.
Remote object management supports Aliyun OSS, S3-compatible storage, and Qiniu Kodo. In Other reference URL bases, enter one HTTP(S) base per line, with each base ending where the object key begins; do not use commas or semicolons as separators. OSS ListObjectsV2 incurs API request charges; private preview uses a 300-second V4 presigned URL, while public preview uses the configured public access URL base. Grant only oss:ListObjects, oss:GetObject for private previews, and oss:DeleteObject when deletion is required. Archive, Cold Archive, and Deep Cold Archive objects are not previewed automatically. Qiniu requires its public access URL base for public previews and private download-token previews; use separate least-privilege credentials for upload, management, and private download where your Qiniu policy requires them.
Deletion requires selecting at most 20 eligible objects, typing the selected count, and acknowledging that cloud deletion cannot be undone. Requests run with at most two concurrent operations and are never retried automatically. Successful operations are shown as "Request successful"; whether storage space is released depends on the provider's deletion and versioning policy. Use a dedicated bucket or prefix, grant only the permissions required, and verify results by scanning the configured scope again. The plugin keeps up to 200 redacted local diagnostic records of completed delete requests; they never participate in remote-existence, reference, or deletion decisions, and do not contain presigned preview URLs or credentials.
The image browser manages both local images and remote objects from supported hosting configurations.


Note: Only supports Wiki → Markdown conversion, reverse conversion is not supported.

| Provider | Status | Description |
|---|---|---|
| Aliyun OSS | ✅ Supported | OSS V4 upload, ListObjectsV2, folders, public/private preview, and guarded delete |
| Qiniu Cloud | ✅ Supported | Token upload, remote list/folders, public/private preview, and guarded delete; public access URL base required |
| S3 Compatible Storage | ✅ Supported | AWS SigV4 upload and remote management; supports MinIO, Cloudflare R2, etc. |
| Custom | ✅ Supported | Custom URL, method, headers, and field mapping; upload only |
| Variable | Description | Example |
|---|---|---|
{noteName} |
Current note name (without extension) | my-note |
{date} |
Current date | 2026-05-30 |
{time} |
Current time | 143025 |
{timestamp} |
Unix timestamp (milliseconds) | 1748155225123 |
{counter} |
Incrementing counter | 1 |
{year} / {month} / {day} |
Date components | 2026 / 05 / 30 |
| Variable | Description |
|---|---|
{noteName} |
Current note name (without extension) |
{notePath} |
Current note's directory path |
{year} / {month} / {day} |
Date |
{filename} |
Image filename |
{timestamp} |
Unix timestamp |
| Variable | Description |
|---|---|
{year} / {month} / {day} |
Date |
{filename} |
Filename (without extension) |
{ext} |
Extension |
{hash} |
File content SHA-256 hash (first 16 characters) |
{timestamp} |
Unix timestamp |
{sourceDir} |
Vault-relative parent directory of the source image |
Provider-specific upload paths override the global template. Aliyun OSS, Qiniu, and S3 use these templates; custom HTTP uploaders continue to use the URL returned by their configured JSON response path.
| Variable | Description |
|---|---|
{fileUrl} |
Uploaded file URL (required) |
{fileAlt} |
Alt text |
{fileName} |
Full filename |
{fileBaseName} |
Filename without extension |
{fileExt} |
Extension |
{fileWidth} / {fileHeight} |
Intrinsic image dimensions |
Unknown variables, a missing {fileUrl}, or unavailable requested dimensions cause the uploaded reference to fall back to standard Markdown.
navigator.clipboard API; mobile behavior still depends on the host platform and permissionsZero-Clause BSD (0BSD)