Search code examples
javascriptgoogle-apps-scriptgoogle-docsgoogle-docs-apibinary-image

Convert Binary Image to Image and Insert into Google Doc - Google Apps Script


We have a license for https://www.qr-code-generator.com/ which has an API located here https://www.qr-code-generator.com/qr-code-api/

I'm using Google Apps Script in a Google Doc.

When I make an API call I get Raw Binary Images as a response.

function APICall() {
  var url = "https://api.qr-code-generator.com/v1/create?access-token=dAlKmUnRsrPIFBLY_ix5YU0LRuMsNgM9MnFTmVHJwD4JRAeBmdzrPmmUAqi9zNyX";
  var options = {
    "method": "post",
    "payload":{
    "frame_name": "no-frame",
    "qr_code_text": "https://www.qr-code-generator.com/",
    "image_format": "PNG",
    "qr_code_logo": "scan-me-square",
    "download":1
    }
  };

  var response = UrlFetchApp.fetch(url, options);
  //return "Testing";
  return response;
}

I get the following responses

SVG https://pastebin.com/nF2YHzux

JPG https://pastebin.com/8HCYdeEu

PNG https://pastebin.com/J68U2PMy

This is where I start running into problems.

I can't find a good way to push the actual image of the QR code to my Google Doc.

This is the closest thing I've found but I don't think I can embed an SVG into a Google Doc.

https://dev.to/benjaminblack/using-a-string-of-svg-as-an-image-source-8mo

  let svg = APICall();
  let blob = new Blob([svg], {type: 'image/svg+xml'});
  let url = URL.createObjectURL(blob);
  let image = document.createElement('img');
  image.src = url;
  image.addEventListener('load', () => URL.revokeObjectURL(url), {once: true});

but I get "ReferenceError: Blob is not defined". I'm not sure if this is even possible.

EDIT Include the actual function that is calling APICall():

//This function currently has 2 purposes. I replace any instance of <<QR>> code as the text string that is returned from APICall()
function QRify(){

  var activeDoc = DocumentApp.getActiveDocument();
  var id = activeDoc.getId();
  var doc = DocumentApp.openById(id); //Get the ID of the copy
  
  var head = doc.getHeader();
  var body = doc.getBody(); //Get the body of the copy
  var foot = doc.getFooter();

  var replaceText = "<<QR>>";
  var code = APICall();

  //var img = new Image();
  //img.src = 'data:image/jpeg;base64,' + hexToBase64(code);

  //head.appendChild(img);
  
  let svg = APICall();
  let blob = new Blob([svg], {type: 'image/svg+xml'});
  let url = URL.createObjectURL(blob);
  let image = document.createElement('img');
  image.src = url;
  image.addEventListener('load', () => URL.revokeObjectURL(url), {once: true});
   
  
  Replace Strings with Form variables
    if(head != null){
      head.replaceText(replaceText, code);
    }

   if(body != null){
     body.replaceText(replaceText, code);
   }

   if(foot != null){
     foot.replaceText(replaceText, code);
   }
}

Solution

  • From your showing script, I thought that in this case, the blob can be retrieved from var response = UrlFetchApp.fetch(url, options);. When this is reflected in a sample script, how about the following sample script?

    Sample script:

    In this sample script, <<QR>> in the document body is replaced with the retrieved image blob. So, please put <<QR>> to the document body. And, in this case, as a sample, the active Document is used.

    function sample() {
      // Ref: https://tanaikech.github.io/2018/08/20/replacing-text-to-image-for-google-document-using-google-apps-script/ Author: me
      // Ref: https://stackoverflow.com/q/51912364
      var replaceTextToImage = function (body, searchText, image, width) {
        var next = body.findText(searchText);
        if (!next) return;
        var r = next.getElement();
        r.asText().setText("");
        var img = r.getParent().asParagraph().insertInlineImage(0, image);
        if (width && typeof width == "number") {
          var w = img.getWidth();
          var h = img.getHeight();
          img.setWidth(width);
          img.setHeight(width * h / w);
        }
        return next;
      };
    
      var doc = DocumentApp.getActiveDocument();
      var body = doc.getBody();
      var replaceText = "<<QR>>";
      var code = APICall();
      var blob = code.getBlob();
      do {
        var next = replaceTextToImage(body, replaceText, blob, 200);
      } while (next);
    }
    
    • When this script is run, the image blob is retrieved from var code = APICall();, and <<QR>> is replaced with the image.
    • 200 of replaceTextToImage(body, replaceText, blob, 200) is the image width. Please modify this for your actual situation.

    Reference: