Image Grabber Sketch

This is a shallow dive for an image analyst tool to grab imagery from a website, saving to a local folder and documenting the source URL and date in a metadata.json file. In future, we may want a meta.json sidecar for each image instead of one for the whole collection.

Background: Yesterday, Alison bought a small piece of artwork at Spanish Market from the artist, Brandon Maldonado. I visited his site and purchased another. While there, I wanted to zoom in on his images beyond what the web UI allowed. I used this as an excuse to vibe code an image grabber to the local file system and then a second Ken Burns type of slideshow.

To try out the bookmarklets, drag them to your bookmarks bar. And then visit Brandon's site and press the bookmark.

Squarespace Hi-Res Image Downloader. Drag this link to your bookmarks bar
Image Downloader Squarespace

Brandon's site is https://brandonmaldonado.art/.

I separately vibe-coded a Ken Burns styled slideshow to playback a file system API folder. You can see that here: https://guerin.acequia.io/anysuface/slideshow .

This plays off local data — the bookmarklet could also be changed to PUT the data to a URL for remote viewing.

Image Downloader Bookmarklets

We developed two powerful bookmarklets for downloading images from webpages using the File System Access API. These bookmarklets can directly save images to a user-selected local folder and create a metadata.json file for persistence.

Generic Image Downloader
Drag this link to your bookmarks bar
Image Downloader

Generic Downloader (Expanded)

(async()=>{
  try {
    const imgs = [...document.images];
    if (imgs.length === 0) return alert('No images found.');
    const dirHandle = await window.showDirectoryPicker();
    const meta = [];

    for (let i = 0; i < imgs.length; i++) {
      try {
        const img = imgs[i];
        const res = await fetch(img.src);
        const blob = await res.blob();
        const ext = (img.src.split('.').pop().split('?')[0] || 'png').split('/')[0];

        const fileHandle = await dirHandle.getFileHandle(`image-${i}.${ext}`, { create: true });
        const writable = await fileHandle.createWritable();
        await writable.write(blob);
        await writable.close();

        meta.push({ index: i, url: img.src, dateCaptured: new Date().toISOString() });
      } catch (err) {
        console.error('Failed to save image', err);
      }
    }

    const metaHandle = await dirHandle.getFileHandle('metadata.json', { create: true });
    const metaWritable = await metaHandle.createWritable();
    await metaWritable.write(JSON.stringify(meta, null, 2));
    await metaWritable.close();

    alert('All images saved with metadata.json');
  } catch (err) {
    console.error('Error:', err);
    alert('Something went wrong. Check console.');
  }
})();

Squarespace Hi-Res Downloader (Expanded)

Squarespace Hi-Res Image Downloader
Drag to Bookmarks Bar

(async()=>{
  try {
    const imgs = [...document.querySelectorAll('img[data-src], img[data-image], img[src]')];
    if (imgs.length === 0) return alert('No Squarespace images found.');
    const dirHandle = await window.showDirectoryPicker();
    const meta = [];

    for (let i = 0; i < imgs.length; i++) {
      try {
        const img = imgs[i];
        let url = img.getAttribute('data-src') || img.getAttribute('data-image') || img.src;
        url = url.replace(/\?.*$/, '') + '?format=original';

        const res = await fetch(url);
        const blob = await res.blob();
        const ext = (url.split('.').pop().split('?')[0] || 'jpg').split('/')[0];

        const fileHandle = await dirHandle.getFileHandle(`image-${i}.${ext}`, { create: true });
        const writable = await fileHandle.createWritable();
        await writable.write(blob);
        await writable.close();

        meta.push({
          index: i,
          url: url,
          dateCaptured: new Date().toISOString(),
          originalDimensions: img.getAttribute('data-image-dimensions') || null
        });
      } catch (err) {
        console.error('Failed to save image', err);
      }
    }

    const metaHandle = await dirHandle.getFileHandle('metadata.json', { create: true });
    const metaWritable = await metaHandle.createWritable();
    await metaWritable.write(JSON.stringify(meta, null, 2));
    await metaWritable.close();

    alert('All Squarespace images saved with metadata.json.');
  } catch (err) {
    console.error(err);
    alert('Error occurred. Check console.');
  }
})();

Generic Image Downloader
Image Downloader

Squarespace Hi-Res Image Downloader
Image Downloader Squarespace