Image Attachment Upload

by rocketBANG
5
4
3
2
1
Score: 50/100

Description

Reviews

No reviews yet.

Stats

0
stars
70
downloads
0
forks
37
days
2
days
2
days
1
total PRs
0
open PRs
0
closed PRs
1
merged PRs
0
total issues
0
open issues
0
closed issues
10
commits

Latest Version

README file from

Github

Image Attachment Upload

Obsidian plugin: adds commands to pick an image on your device, upload it to Cloudflare R2, and drop it into the current note — either as an inline embed or as a frontmatter property.

Works on desktop and mobile (signing is done on-device with the Web Crypto API; no SDKs, no CORS setup needed on the bucket).

Commands

  • Upload image and insert inline — opens a file picker, uploads to R2, inserts ![<note name>](<public url>) at the cursor.
  • Upload image and set image property — opens a file picker, uploads to R2, sets the note's image frontmatter property (name configurable) to the public URL.

Command line

With Obsidian's CLI enabled, image-upload:upload does the same job without a file picker, and writes the result straight into a note:

for f in ~/Photos/*.jpg; do
  obsidian image-upload:upload src="$f" file="Dinner" append height=500
done

Use file=/path= with append or property to say where the URL should end up. Without them the upload still happens, but the URL is currently lost — Obsidian stops waiting for a CLI handler after a few tens of milliseconds, well before an upload finishes, so the returned URL never reaches stdout and can't be piped or captured. Failures do get reported, so a silent run is a successful one.

Flag Meaning
src=<path> Image to upload — vault-relative, or an absolute path. Required.
max=<px> Longest edge to downscale to, overriding the setting. 0 uploads full size.
quality=<1-100> Encoder quality, overriding the setting.
file=<name> / path=<path> Note to write into, resolved like other Obsidian CLI commands.
append Append the embed to that note.
property Set that note's image property to the URL.
alt=<text> Alt text for the embed. Defaults to the note name.
width=<px> Display width for the embed.
height=<px> Display height; the width follows from the image's aspect ratio.

height= is the useful one for a batch of mixed portrait and landscape shots — every image ends up the same height down the note.

Resizing

Images are downscaled so their longest edge fits Maximum image size (1600px by default) and re-encoded at Image quality (85). This applies to the commands and the CLI alike. A 12MP phone photo typically lands around a tenth of its original file size, with enough resolution left for a HiDPI screen. Set the maximum to 0 to upload untouched.

JPEG, PNG, and WebP are resized; anything else uploads byte-for-byte. PNGs stay lossless, so quality doesn't apply to them. Resizing happens on a canvas, which bakes in EXIF rotation and drops the remaining metadata. If an image can't be decoded it's uploaded as-is rather than failing.

Setup

  1. Create an R2 API token (Object Read & Write, ideally scoped to one bucket) — this gives you an access key ID + secret.
  2. Serve the bucket publicly via a custom domain (or the bucket's r2.dev development URL).
  3. Fill in the plugin settings: endpoint (https://<account-id>.r2.cloudflarestorage.com), bucket name, path template, and the public base URL.
  4. Enter the access key ID and secret access key, or turn on Store credentials in the keychain first and select Link on each to pick an existing keychain entry or add a new one.

Object keys follow the path template (default /{year}/{mon}/{day}/{filename}), with a short random suffix added to the filename to avoid collisions.

Where the credentials are kept

Store credentials in the keychain picks between the two options:

  • Off (default). The credentials sit in plaintext in the plugin's data.json inside your vault, as most uploader plugins do. They travel with the vault, so setup happens once. Scope the R2 token to the one bucket, and keep data.json out of any git repo your vault lives in.
  • On. The credentials go into Obsidian's keychain, encrypted by the OS (macOS Keychain, Windows DPAPI, or a Linux secret store such as gnome-keyring/kwallet), and data.json holds only the name of the entry. Turning this on clears the plaintext copy. The keychain is per-device and isn't synced, so you link the credentials again on each device — and if a device's secret store isn't working, uploads there fail until you link them or switch back to plaintext.

Installing via BRAT

Add rocketBANG/obsidian-image-attachment-upload as a beta plugin in BRAT.

Manually installing the plugin

Copy main.js and manifest.json into <vault>/.obsidian/plugins/image-attachment-upload/.

Development

Requires NodeJS v22.13+ and pnpm 11.

  • pnpm i to install dependencies.
  • pnpm run dev to start compilation in watch mode (produces main.js).
  • pnpm run build for a production build.
  • pnpm run lint to lint.

Releasing

  • Run pnpm version patch (or minor / major) after updating minAppVersion manually in manifest.json if needed — this bumps manifest.json, package.json, and versions.json.
  • Push a tag matching the exact version number (no v prefix); the release workflow builds the plugin and drafts a GitHub release with main.js and manifest.json attached.