Download Images from Retool

Hi community,

I was wondering if there was a way for users of public links to download images that are shown as image components in an app. Best would be a way to download several images as folder/zip through clicking a button and triggering an export event.

This post may help.

1 Like

Hello @Leon,

Maybe try it like this:

  1. Create a REST query that returns the base64 encoded image data for the image you want to download.
  2. Create a JavaScript query that triggers the REST query and then downloads the image data as a file.
  3. Add a button to your app that triggers the JavaScript query when clicked.

Here is an example of a JavaScript query that you can use:

// Get the base64 encoded image data for the image you want to download.
const imgData = await api.trigger({
  name: "GetImageBase64",
  additionalScope: {
    imageUrl: "https://example.com/image.jpg",
  },
});

// Download the image data as a file.
utils.downloadFile({
  base64Binary: imgData.base64Binary,
  fileName: "image.jpg",
  fileType: "image/jpeg",
});

You can also use the JSZip library to download multiple images as a folder/zip file. Here is an example of how to do that:

const zip = new JSZip();

// Add each image to the zip file.
for (const image of images) {
  const imgData = await api.trigger({
    name: "GetImageBase64",
    additionalScope: {
      imageUrl: image.url,
    },
  });

  zip.folder("images").file(image.fileName, imgData.base64Binary, { base64: true });
}

// Generate the zip file and download it.
zip.generateAsync({ type: "base64" }).then(function (base64) {
  utils.downloadFile({
    base64Binary: base64,
    fileName: "images.zip",
    fileType: "application/zip",
  });
});

Once you have created the REST query and JavaScript query, you can add a button to your app that triggers the JavaScript query when clicked. You can also add the button to a modal so that users can select which images they want to download before downloading them.

Hope this helps.

:grinning:

Patrick

4 Likes

nice one, thank you!

1 Like

You may want to create a promise for each fetching and await all to fetch "in parallel". The zipping must done sequentially (with jszip at least). Retool has documented the promise use.
Makes quite a difference for large or multiple files.