1

I am trying to insert all images from a Google Drive folder into a Google document. But on insertImage I always get an "invalid image data" error.

function myFunction() {
  var folder = DriveApp.getFolderById(id);
  var files = folder.getFiles();
  while (files.hasNext()) {
     var file = files.next();
     var img = file.getBlob();
     var imgDoc = DocumentApp.getActiveDocument().getBody().insertImage(0, img);  
   }
}

There are numerous examples that explain how to do this, and all say to get the image blob and use that to insert. Is there something about this code that gives an incorrect image blob?

Tanaike
  • 181,128
  • 11
  • 97
  • 165
Bryan Gentry
  • 873
  • 1
  • 7
  • 24
  • If there are only images in the folder, can I ask you about the mimeTypes of image files you want to insert? – Tanaike Apr 02 '19 at 03:26
  • @Tanaike they are all image/jpeg – Bryan Gentry Apr 02 '19 at 10:24
  • 1
    Thank you for replying. jpeg file can be inserted. So I would like to confirm the jpeg file which occurs the error. For example, in order to confirm your situation, can you provide the sample jpeg file which occurs the error? – Tanaike Apr 02 '19 at 22:33
  • With further investigation (and use of try/catch) I realized that some images in the folder were working just fine. The ones causing the error seem to be large, 10+ megabytes. Is there a size limitation as to what will work with insertImage? Here is one of the images with the issue: https://drive.google.com/file/d/166blmiknqJYqwFEhSkbb_diwmJvt16l2/view?usp=sharing – Bryan Gentry Apr 03 '19 at 10:21
  • Thank you for replying. I could understand about the issue. I proposed a workaround as an answer. Could you please confirm it? – Tanaike Apr 04 '19 at 00:51
  • Did my answer show you the result what you want? Would you please tell me about it? That is also useful for me to study. If this works, other people who have the same issue with you can also base your question as a question which can be solved. If you have issues for my answer yet, I apologize. At that time, can I ask you about your current situation? I would like to study to solve your issues. – Tanaike Apr 10 '19 at 22:48

1 Answers1

3

How about this answer?

Hypothesis and Experiment:

From my experiment, in the Spreadsheet, when an image is inserted by insertImage() in Class Sheet, the limitation is due to the image area (pixels^2) rather than the file size of it. The maximum area of image which can be inserted is 1,048,576 pixels^2. Ref

From this situation, I thought that your issue is also related to the case of Spreadsheet. The limitation of insertImage() in Class Body might be due to the area of image. So I experimented as follows.

  • Image with the following sizes can be inserted.

    • 5000 pixels x 5000 pixels
    • 25000 pixels x 1000 pixels
    • 1000 pixels x 25000 pixels
  • Image with the following sizes can NOT be inserted.

    • 5001 pixels x 5001 pixels
    • 5000 pixels x 5001 pixels
    • 5001 pixels x 5000 pixels

As the result, it was found that the limitation of area is 25,000,000 pixels^2.

About your issue:

In your case, the image size of the shared image is 6240 pixels x 4160 pixels. This area is 25,958,400 pixels^2. This area is larger than the value (25,000,000 pixels^2) retrieved above experiment. By this, it is considered that the error occurs.

Workaround:

In order to avoid this limitation, how about this workaround? In this workaround, when the image size is more than 25,000,000 pixels^2, the image size is decreased using Drive API. The modified script is as follows.

Modified script:

function myFunction() {
  var folder = DriveApp.getFolderById(id);
  var files = folder.getFiles();
  while (files.hasNext()) {
     var file = files.next();
     var img = file.getBlob();

     // --- Following script was added.
     var url = "https://www.googleapis.com/drive/v3/files/" + file.getId() + "?fields=imageMediaMetadata(height%2Cwidth)%2CthumbnailLink&access_token=" + ScriptApp.getOAuthToken();
     var res = UrlFetchApp.fetch(url).getContentText();
     var obj = JSON.parse(res);
     if (obj.imageMediaMetadata && (obj.imageMediaMetadata.width * obj.imageMediaMetadata.height) > 25000000) {
       var width = 1000;
       var tlink = obj.thumbnailLink.replace(/=s\d+/, "=s" + width);
       img = UrlFetchApp.fetch(tlink).getBlob();
     }
     // ---

     var imgDoc = DocumentApp.getActiveDocument().getBody().insertImage(0, img);
   }
}
  • In this modification, as a sample, the image size is reduced with the width of 1000 pixels. If you want to modify this, please modify var width = 1000.
  • I think that in your script, Drive API has already been automatically enabled because the class DriveApp is used. But if the error related to Drive APi occurs, please check whether Drive API is enabled at API console.

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • So this looks like it will work but it actually reveals the solution to my larger problem. The only reason I was inserting images into a document was to resize them and then save the smaller image in a new file. But it looks like I can use this method to get a resized thumbnail and skip having to insert it into a document. Thanks! – Bryan Gentry Apr 20 '19 at 10:30
  • @Bryan Gentry Thank you for replying. I'm glad your issue was resolved. Thank you, too. – Tanaike Apr 20 '19 at 23:01