obsidian-dataview icon indicating copy to clipboard operation
obsidian-dataview copied to clipboard

Support for images in fields

Open SkepticMystic opened this issue 3 years ago • 12 comments

I am not sure if this is possible, but maybe it can be done. I would like to be able to link to a remote or local image in a yaml field, and have dataview render that image in preview mode.

So something like:

---
image: ![](URLtoimage.com/image.jpg)
# OR
image: [](URLtoimage.com/image.jpg)
# OR
image: URLtoimage.com/image.jpg
---

Where you could then have a table calling for the image field

table image from ""

I know yaml won't render the image in preview mode, but perhaps dataview could have an image type which passes the image path to <img src="{{path}}"> or something.

SkepticMystic avatar Mar 25 '21 07:03 SkepticMystic

Yes, that's possible. I'm wondering what the most convienent syntax would be - probably just the markdown link syntax (![]...), as you suggest?

blacksmithgu avatar Mar 30 '21 00:03 blacksmithgu

For external images, I think [ ]( ) works. Ideally one shouldn't have to put an ! to make it work, but that's small.

Would this feature be able to work with local images to? I guess the img tag can take an internal src? Because then Wikilink images might work too ![[image.png]]

SkepticMystic avatar Mar 30 '21 06:03 SkepticMystic

I like this idea too - using ![image] to show local images in a result table would be fab.

symph0nic avatar Apr 12 '21 14:04 symph0nic

I like this idea

calpa avatar Sep 07 '21 15:09 calpa

Interesting! It might make my custom JS code obsolete.

Below I share my handmade image-from-frontmatter rendering approach for some "how do they overcome of such feature" context 😄


Currently, in YAML front matter I have e.g.:

thumbnail: "084 Interstellar Backdoor (x1).png"

then in dataviewjs I have:

const {DataviewHelpers} = customJS;

dv.table(
	[
		"thumbnail",
		"something else",
	],
	dv.pages(`"${dv.current().file.folder}"`)
		.filter(page => page.file.name !== dv.current().file.name)
		.map(page => [
			renderThumbnailOf(page),
			"other value",
		])
);

function renderThumbnailOf(page) {
	const path = `${page.file.folder}/${page.thumbnail}`;
	const containerStyle = `
		height: 100px;
		width: 100px;
	`;
	return `
		<div style="${containerStyle}">
			${DataviewHelpers.renderThumbnail({
				thumbnailPath: path,
				type: "bg",
			})}
		</div>
	`.trim();
}

and then, last but not least, shared helper function:

class DataviewHelpers {
    renderThumbnail({thumbnailPath, type}) {
        const abstractFile = app.vault.getAbstractFileByPath(thumbnailPath);
        const resourcePath = abstractFile
            ? app.vault.getResourcePath(abstractFile)
            : null;

        if (!resourcePath) return null;

        if (type === "bg") {
            const style = `
                width: 100%;
                height: 100%;
                background-image: url('${resourcePath}');
                background-repeat: no-repeat;
                background-position-x: center;
                background-position-y: center;
                background-size: contain;
            `;
            return `<div style="${style}"></div>`;
        }

        if (type === "img") {
            const style = `
                width: 100%;
                object-fit: contain;
            `;
            return `<img style="${style}" src="${resourcePath}">` ;
        }

        throw Error(`Thumbnail type "${type}" is not supported.`)
    }
}

Another use case I have is with multiple thumbnails (I render them all inside a single table cell), like:

thumbnails:
  - "066 Grumman F-11 Tiger - F11 Keycap (social media).png"
  - "067 Kung Fury Time Travel - Enter and Backslash Pipe Keycaps (social media).png"

nkoder avatar Sep 09 '21 22:09 nkoder

@nkoder thank you very much for sharing your code.

Dataview plugin version 0.5.38 on obsidian 0.14.15

Here DataviewJS working and rendering local images inside dv.table by using:

"![micro.jpg](resourcePath)"

where

resourcePath = app://local/C:/Users/serepasare/OneDrive/D_PERSONAL/obsidiana/micro.jpg?1598932447000

resourcePath obtained using @nkoder code.

juangimenezg avatar Aug 04 '22 04:08 juangimenezg

Can someone work out the different image cases and then help me separate out the support and non supported parts? It's been a bit janky and I need a hand.

AB1908 avatar Oct 18 '22 22:10 AB1908

My goal was to have a book library with LOCAL Cover images using YAML and DataView.

Just put your normal png link in to YAML and put " on each side.

---
Cover: "![[YourImageName.png]]"
---

Then simply table for Cover like with any other text.

```dataview
TABLE
Cover

CreepyBasti avatar Nov 02 '22 06:11 CreepyBasti

Your use case should work with embed().

AB1908 avatar Nov 12 '22 11:11 AB1908

@AB1908 Can you explain? I've tried it like embed(Cover) as Cover but it's not working for me

eenpadvinder avatar Nov 22 '22 09:11 eenpadvinder

I can display local images only using embed() but can’t do the same for online images. Any ideas? this is how I use it

---
Cover: "YourImageName.png”
---

then

```dataview
TABLE
embed(link(Cover)) as Cover

Moaness avatar Feb 12 '23 21:02 Moaness

I can display local images only using embed() but can’t do the same for online images. Any ideas? this is how I use it

---
Cover: "YourImageName.png”
---

then

```dataview
TABLE
embed(link(Cover)) as Cover

Here we go,

```dataview
TABLE
  EmbededCoverImg AS CoverImg
FLATTEN choice(typeof(cover)="link",
  embed(link(meta(
    choice(
      typeof(cover)="link",
        封面, this.file.link
      )
    ).path, "100")), "![anyName|100]("+ cover +")") AS EmbededCoverImg
```

Or, with dataviewjs

```dataviewjs
const columns = ["CoverImg"];
const rows = dv.pages('"path/to/your/repo/if/necessary"')
  .map(page => {
    const coverImg = (function() {
      switch (dv.func.typeof(page.cover)) {
        case "link":
          return dv.fileLink(`${page.cover.path}`, true, 100);
        case "string":
          return "![anyName|100](" + page.cover + ")";
        default:
          return "";
        }
      })()

      return [
        coverImg,
      ];
  })

dv.table(columns, rows);
```

And a metadata should be

  • online picture: cover: https://url/to/your/online/picture
  • local picture : cover: "![[path/to/your/local/picture]]"

DehanLUO avatar Apr 05 '24 12:04 DehanLUO