Google Slides API — a deep dive on its powerful image manipulation methods

Romain Vialard
4 min readApr 24, 2020

Use Google Apps Script and the Google Slides API to create a card game like Dobble.

What am I talking about?

Dobble (Spot It! in the US)

A speedy observation card game. During the game, players have to spot the identical symbol between two cards as quickly as possible.
=> learn more on Wikipedia

Google Apps Script

A rapid application development platform that makes it fast and easy to create applications that integrate with G Suite. You write code in modern JavaScript and have access to built-in libraries for favorite G Suite applications like Gmail, Calendar, Drive, and more. There’s nothing to install — we give you a code editor right in your browser, and your scripts run on Google’s servers.
=> learn more on the official documentation

Google Slides API

This API lets you create and modify Google Slides presentations. Apps can integrate with the Google Slides API to create beautiful slide decks automatically from user- and system-provided data.
=> learn more on the official documentation

The Dobble Algorithm

There are several articles and YouTube videos explaining the maths behind the game. I’m focusing on using the Google Slides API so I simply reused a Javascript function shared on Stack Overflow.

This function returns a two-dimensional array of integers, any two arrays always sharing one, and only one, matching integer.

The function output — if we want 8 symbols on each card, like in the real Dobble game, the function will return an array of 57 arrays, each one containing 8 integers, each between 0 and 56.

From numbers to images in Slides

Insert images in Slides

Now we just need an image for each integer returned by the function (in my case I uploaded a bunch of images in a Google Drive folder), and we can insert all those images in slides using the Google Slides API, it’s quite easy:

SlidesApp.create(“my card deck”).appendSlide().insertImage(imageUrl);

But I need to insert 8 images per slide and I don’t want one to appear on top of another one. Luckily you can easily set position of each image (set the position from the upper-left corner of the page + the size of the image):


Replace existing images / use a template

I thought it would be easier to start from a template containing images, copy said template and replace the images (as there’s a replace method available for images!):

Each “i” symbol is an image with a square aspect ratio
for (var i = 0; i < deck.length; i++) {
// each slide / card is a copy of our template
var card = presentation.appendSlide(card_template);
// existing images in the template are used as placeholders
var placeholders = card.getImages();
for (var j = 0; j < placeholders.length; j++) {
// and replaced by our real images
I’m building a card deck on the paw patrol universe for my son, 6 images per card only

Rotate images

We can also apply a random rotation on each image.

var image = placeholders[j].replace(imageUrl);
image.setRotation(Math.floor(Math.random() * 360));
shadow + reflection

Many more methods are available to manipulate images, you could use scaleWidth(ratio) to randomly change the size of each image or even recolor, add a reflection or a shadow on each image (basically every manipulations you can do from the Slides editor UI).

Try it

Here’s the full Apps Script code to generate a card deck from a bunch of images in Google Drive:

And a step-by-step tutorial:

A note on authorization scopes

In this Apps Script code, in addition to the Google Slides API, I used the Google Drive API to:

  • Retrieve all images in a specific folder Drive.Children.list(DRIVE_FOLDER_ID, { q: “mimeType contains ‘image/’ and trashed = false” }).items;
  • Make a copy of a Google Slide template and put that copy in the same folder
    Drive.Files.copy({ parents: [{ id: DRIVE_FOLDER_ID }] }, SLIDES_TEMPLATE_ID);

In Apps Script, you can do that either with DriveApp or the Advanced Drive Service. I used the later because it offers the ability to reduce the permissions we need.

  • With DriveApp, I need to use the full drive scope, which allow the script to read, edit and delete everything in Drive
  • With the advanced service, I will still need a global read access to get all images(using drive.readonly scope) but I can combine that with the drive.file scope which only allows the script to create new files, not edit existing ones already created by the user in his Drive.

Best would be to have a less permissive read scope, where user would only authorize the script to access files inside a specific folder but that’s not (yet?) available.



Romain Vialard

Google Developer Expert, creator of several successful add-ons for Gmail, Drive,...