How to display local images with <img>-tag and keep portability?

Things I have tried

  • Referencing local images works perfectly with markdown. I can then reference my images using a relative syntax (_media/image.png).
  • img-tags works fine as long as the src is an URL. I read that I can also reference local images using absolute paths with the img-tag, but I’ve not tested this myself.

What I’m trying to do

I’d like a portable way (works for both desktop and mobile) to display local images in html blocks (tables).

Is there a way to achieve this? If not, is it on the roadmap?
Would it be possible to write a plugin that “intercepts” image links in html and redirects to the absolute path of the image? I’d prefer not to alter the actual .md-files…

1 Like

I made a simple plugin to solve this. It works on desktop, but I’ve not tested it on mobile.

import { Plugin } from "obsidian";

export default class HtmlLocalSrcPlugin extends Plugin {
  async onload() {
    this.registerMarkdownPostProcessor((element) => {

      const targetLinks = Array.from(element.getElementsByTagName("img")).filter(
        (link) =>
          link.src.contains("_media")
      );

      //@ts-ignore
      let base_path = this.app.vault.adapter.basePath;
      console.log('base_path: ' + base_path)
      const active_file_path = this.app.workspace.getActiveFile().path;
      const active_path = active_file_path.substring(0, active_file_path.lastIndexOf("/"));
      console.log('active_file_path: ' + active_path)
      for (const link of targetLinks) {
        let clean_link = link.src.replace('app://obsidian.md/', '')
        console.log('clean_link: ' + clean_link)
        let full_link = 'app://local' + base_path + '/' + active_path + '/' + clean_link
        console.log('full_link: ' + full_link)
        link.src = full_link

        }
    });
  }
}
2 Likes

How did you install this plugin? I made a manifest file and added your code as the main.js file. Then I put these in a folder in the plugins folder.

When I try to turn it on in Obsidian, it says it fails to load.

You’ll need to compile the code to make it work. Start with the template plugin and replace the code there.

1 Like

I’ve updated the code since I made the first post. It’s now tested and works on iOS. Have not tested on Android.

import {Platform, Plugin, TFile} from "obsidian";
import type { MarkdownView } from 'obsidian';
import {platform} from "os";

export default class HtmlLocalSrcPlugin extends Plugin {
  async onload() {
    this.registerMarkdownPostProcessor((element, ctx) => {

      const targetLinks = Array.from(element.getElementsByTagName("img")).filter(
        (link) =>
          link.src.contains("_media")
      );
      const active_file = this.app.workspace.getActiveFile();
      let active_path = this.app.vault.getResourcePath(active_file)
      active_path = active_path.substring(0, active_path.lastIndexOf("/"));
      //console.log('active_file_path: ' + active_path)
      for (const link of targetLinks) {
        let clean_link = link.src.replace('app://obsidian.md/', '')
        // For iOS
        clean_link = clean_link.replace('capacitor://localhost/', '')
        //console.log('clean_link: ' + clean_link)
        let full_link =  active_path + '/' + clean_link
        //console.log('full_link: ' + full_link)
        link.src = full_link
        if(Platform.isMobile) {
          console.log("Running on mobile platform - setting object fit and height of img")
          link.style.objectFit = "contain"
          link.height = 100
        }
        }
    });
  }
}
1 Like

I figured out how to compile the plugin using the example plugin. Thank you again for the code and the updated code.

Now I am trying to get it to work on Android and in live preview mode but this is really great. Thank you.

For Android I tried adding clean_link = clean_link.replace("file://localhost/", ""); for Android but that didn’t work. Not sure what part of the file path to remove on Android.

can you share your plugin?

en…en I made one . thank your code. @ c3p0

how to support live preview ?did you succeed ?

It isnt work on Ubuntu22, i place the master folder in workspace/.obsidian/plugins, and have confirmed the plugin shows in “Setting - Community Plugins - Installed Plugins”, is there anything wrong?

I wrote a plugin to solve this problem: csdjk/lcl-obsidian-html-local-img-plugin (github.com)

nice job

That’s working for me in reading mode but your example gif looks like it’s in live preview mode but that doesn’t seem to work for me.

Either way I really appreciate you and @CheapMeow both offering options to get it working in reading mode, that’s a huge improvement for when I need portability!

thank your code. It does not support the path with “… /” The picture of the upward path can be updated as well