Recently I needed discovered that I had a lot of similar pictures in my vault because it seemed easier to paste new ones on the spot. Unfortunately using different pictures for the same concepts creates a messy knowledge graph which is difficult to remember. Hence, I needed a solution with following features:
- Works out-of-the-box, no configuration necessary
- Scans down a directory tree and collect all images
- Presents images in a multi-column table format along with their filenames
- Allow drag and drop of images from the gallery into notes
- Allow searching images by name
Here’s a crude dataviewJS snippet that does something like that:
The screenshot below shows a picture gallery created by a dataviewJS query in the left pane and a new note in the right pane. The picture in the Untitled note was dragged from the gallery and dropped into that note.
DataViewJS Query
~~~dataviewjs
/**
* Picture Gallery (dvjs)
*
* Searches the current folder and its subfolders (`deepScan = true`) for
* pictures by file extension.
* Configuration Options:
* - `pictureExtensions` - file extensions of the pictures to include
* - `pictureColumns` - the number of picture columns in the gallery table.
* **Note** each picture colums has an associated `File` column, hence the table
* has twice as many columns in total.
* - `pictureSize` - the size of the preview image
* - `deepScan` - `true` to recurse into subfolders
*/
const
pictureExtensions = ["jpg", "jpeg", "png", "webp", "svg"],
pictureColumns = 2,
pictureSize = "100",
deepScan = true, // <- set to `false` to search current folder only
current = dv.current(),
vault = app.vault,
currentFolder = await vault.getFolderByPath(current.file.folder),
folders = [currentFolder ?? vault.getRoot()];
let pictures = [];
while (folders.length > 0) {
// inspect all subfolders for pictures
folders.shift().children
?.filter(c => c.type === "folder")
.forEach( f => {
pictures = [
...pictures,
...f.children?.filter(p => pictureExtensions.includes(p.extension))
];
if (deepScan) {
folders.push(f);
}
});
}
if (pictures.length > 0) {
const header = [];
for (let i = 0; i < pictureColumns; i++) {
header.push("Preview","File");
}
const rows = [];
let currentRow = [];
dv.array(pictures)
.sort(p => p.name)
.forEach(p => {
if (currentRow.length === header.length){
rows.push(currentRow);
currentRow = []
}
currentRow.push(
dv.fileLink(p.path,true,pictureSize),
dv.fileLink(p.path,false,p.name));
});
rows.push(currentRow); // the last row
dv.table(header,rows);
} else {
dv.paragraph(`_No ${pictureExtensions.join(",")} images found._`)
}
~~~
To use that snippet you need to have the Dataview plugin installed and configured to allow JavaScript queries.
Picture Gallery Styling
If you have the cards layout activated, i.e the cssclasses: cards
property in the page’s frontmatter, the gallery does not look too shabby:
A Plugin Solution
For a professionally looking solution you may want to check out the Masonry Note Gallery for Obsidian plugin.