Scaling down large image files using the get thumbnail API

As digital cameras evolve, including the ones in our smartphones, photos produced by them constantly increase in resolution and file size. For instance, on my current smartphone, the average file size of pictures goes between 6-8 MB, when the ones produced by my 3-year-old smartphone average 2-3 MB.

Having a large file size is not a problem when previewing images directly in the Dropbox website or the Dropbox mobile apps as these surfaces are optimized for large files, but presents challenges when interacting with other APIs.

If you’re transferring your images to a third party API for processing (like an image recognition AI), you can easily hit their size limits if you’re uploading large files. Additionally, scaling images down to a smaller size and resolution will significantly reduce upload and processing time for those API tools.

The Dropbox API offers a solution for this with our get_thumbnail API.

In this article, we will cover how to:

  1. Use the get_thumbnail API on a conceptual level
  2. Test the API with a few image samples
  3. Scale down images within a Dropbox folder using a script written with Node.js and the Dropbox JavaScript SDK

Using the get_thumbnail API

The Dropbox API offers a great way to retrieve scaled down images with the get_thumbnail and get_thumbnail_batch APIs. These APIs offer several options to get a scaled down version of any image that is smaller than 20MB and that has any of these formats: jpg, jpeg, png, tiff, tif, gif and bmp.

When you use these APIs, the files in Dropbox are not modified, but you get in the response the bits for images according to the parameters in the request.

Looking at the API documentation for get_thumbnail, there are three important parameters that you need to pass in your request: format, size, and mode.

format: refers to the format you want the output to be, which can be jpeg or png.

size: defines the final resolution of the image. There is a predefined range of options that go between 32 by 32 px to 2048 by 1536 px. You can find all the options in the API documentation for get_thumbnail.

mode: defines how images are scaled down. It can have any of the following three values:

  • strict – Scale down the image to fit within the given size
  • bestfit – Scale down the image to fit within the given size or its transpose
  • fitone_bestfit – Scale down the image to completely cover the given size or its transpose

Testing the API with some image samples

Let’s test the API using different parameters for two photos that I took with my current smartphone from a hidden gem in Silicon Valley in both portrait and landscape orientations. We will use 2048×1536 as the size parameter since at the time of writing, it’s the largest file size you can get with the get_thumbnail API.

Portrait of art fixture in San Francisco
Portrait: 3024×4032 px 5.3 MB

Landscape image of art fixture in San Francisco
Landscape: 4032×3024 px 5.7MB

Results for the portrait image with 3024×4032 px, file size 5.3MB and 3:4 aspect ratio:

Parameters Final Dimensions (w x h) Final aspect ratio Final Size
w2048h1536 strict 1152 × 1536 3:4 438 KB
w2048h1536 bestfit 1536 × 2048 3:4 759 KB
w2048h1536 fitone_bestfit 2048 × 2731 3:4 1.3 MB

Results for the landscape image with 4032×3024 px, file size 5.7MB and 4:3 aspect ratio:

Parameters Final Dimensions (w x h) Final aspect ratio Final Size
w2048h1536 strict 2048 × 1536 4:3 839 KB
w2048h1536 bestfit 2048 × 1536 4:3 839 KB
w2048h1536 fitone_bestfit 2731 × 2048 4:3 1.4 MB

You notice that in the result for both orientations, fitone_bestfit produced the highest quality image and strict the lowest one. You can see how the size of the file has been significantly reduced and now it should be possible to use this file with most services. Also notice that in no case was the aspect ratio of the image modified.

You may wonder, what happens when you try to get the thumbnail specifying dimensions that are higher than the original file? Let’s try this with a much smaller original image.

Results for an image with 768×1024 px, file size 211KB and 3:4 aspect ratio:

Parameters Final Dimensions (w x h) Final aspect ratio Final Size
w2048h1536 strict 768 × 1024 3:4 211 KB
w2048h1536 bestfit 768 × 1024 3:4 211 KB
w2048h1536 fitone_bestfit 768 × 1024 3:4 211 KB

So basically, independently of the parameters, as long as the requested size isn’t smaller than the original in any dimension, we will get the original size, but at the very least could help you to change the file format if you need so.

A note of caution. When you get a thumbnail using the API, the response will contain a subset of the file metadata with it (such as location and time when the photo was taken), but none of the original metadata will be copied onto the new file. You can see this in the below snapshot where I compare the metadata displayed by Finder for both the original (left) and the final (right) images.

Image of metadata being compared for each photo
Metadata in original (left) and thumbnail (right) images

If you are interested in exploring more this API, you can easily test different parameters using the Dropbox API Explorer.

Node.JS script to scale down images within a Dropbox folder

Now let’s see some code. With the above information at hand I’m going to show you a script that scales down all the images in a specified folder that are over a specified size limit and then moves the originals to a nested folder (so no data is lost), but with the benefit that when the script finishes running, all the images at the current folder level will be below the file size limit.

Note: in order to run the script, you’ll need a Dropbox access token. To quickly follow along, you can copy a short-lived token from the API Explorer. When building an integration, do not use this token. Instead, pick an approach below to obtain an access token.

First time building a Dropbox app? Our Getting Started guide will walk you through app setup to an access token you can use in your integration.
Do your users need to interact with their Dropbox data? Head over to our OAuth guide for information on how to build an OAuth Flow. There’s also a blog post with a sample OAuth Flow implementation in Node.js.

The behavior of this script is shown in the below flowchart:

Flowchart overview of the sample script used in article

An important thing to consider is that the thumbnail data makes a roundtrip to the machine running the script. Technically, we could simplify the above flow by using the batch thumbnail download, but this will create potentially large responses from Dropbox so it is better suited when you request small images or for backend processing.

For the script, we will use Node.JS and the Dropbox JavaScript SDK. A Node.JS version higher than 8.3 is required.

To run the script follow these steps:

1. Install Node.JS
2. In a directory, create an empty file named scaledownimgscript.js
3. Copy and paste the contents of this GitHub file into your scaledownimgscript.js file
4. Update the following variables: DROPBOX_ACCESS_TOKEN, FOLDER_PATH, FORMAT, SIZE, MODE, SIZE_LIMIT (optional – controls the size of images filtered out)
5. In the same folder where you have the script, run the following two commands:
npm install dropbox isomorphic-fetch
node -e 'require("./scaledownimgscript").run()'

The script will run and show a message in terminal every time that an image is scaled down and the original gets moved.

Where to go from here

The Dropbox API has many hidden gems like the get_thumbnail endpoint that can help you improve your integration. If you discover your own or want us to cover something specific, then please reach out on the Dropbox API Twitter or the Developer Forums.

For more Dropbox tutorials and technical guides, check out our previous blog posts or developer reference page.

 

Build with Dropbox today at   www.dropbox.com/developers