Google Docs Add-On - Dealing with Images

248 views Asked by At

I'm trying to create a Google Docs add-on in which someone:

  • Selects an image
  • Clicks a menu item
  • A dialog is displayed, showing the image (on a canvas) with a couple tools
  • Canvas is modified using tools
  • Canvas data is saved and replaces the original image
  • Meta data for the image is saved, so it can be re-edited from the original.

I know how to get the image selection (from the GS code) and trigger the menu item and dialog. I also know how to do all of my custom code things.

I need to know:

  • How to get the original image URL (or extract it as a base64 string) that I can put in to a canvas
  • Replace the image and save it in the document.
  • Save metadata on a per-image basis so it can be re-edited.

Examples would be awesome, though links to documentation would also be great. I've found a lot of things, but nothing concrete on how to extract the data as anything but a blob.

1

There are 1 answers

0
samanime On

(This answer is a work-in-progress. Starting an answer to put the bits as I figure them out. If someone else helps me figure out the missing bits, I'll accept theirs instead of this one).

How to get the original image URL (or extract it as a base64 string)

As far as I can tell, there isn't a way to get the default URL. I was however able to get the base64 string. It's slightly convoluted, but works.

Code.gs

// Gets an InlineImage in some way. I'm using the currently selected image,  
// but that's irrelevant to the code sample.
// @return {InlineImage}
function getImage() {
    // gets the InlineImage element somehow
}

// Gets the actual data URI.
// Note: this function uses image/png only. You can change this by changing
// it in the two places, or using a variable. Just be sure the two spots 
// match.
// @return {string}
function getDataUri() {
    return 'data:image/png;base64,' + Utilities.base64Encode(getImage().getAs('image/png').getBytes());
}

MyDialogJavaScript.html

$(function () {
    google.script.run
   .withSuccessHandler(function (data) { console.log(data); })
   .withFailureHandler(function (err) { console.log('failure: ' + err); })
   .getDataUri();
});

An important note: you must SandboxMode.IFRAME when creating the dialog or else you'll get something like:

Rejecting <img>.setAttribute('src', blahblahblah

This is apparently due to a limitation in the Caja compiler normally used. See the answer here for more info: Using base64-encoded images with HtmlService in Apps Script