1

I'm using the google sheets scripting language, and I want to get the ratio of an image from a web link, e.g. this flag.

I have seen a way to do it here, but I want to return the ratio from the function, not put it in a random cell.

So far I have managed to get this, which doesn't seem to work.

function imageSize(imgUrl) {
  if  (typeof imgUrl == 'undefined') {
    imgUrl = 'http://www.google.com/intl/en_ALL/images/logo.gif';
  }
  PropertiesService.getScriptProperties().setProperty('ratio', 0);

  var t = '';     
  t += '<script>\n';
  t += 'function hd(){\n';
  t += 'var img = new Image();\n';
  t += 'img.onload = function() {\n';
  t += "google.script.run.returnVal(this.width / this.height);\n";
  t += '}\n';
  t += "img.src = '" + imgUrl + "';\n";
  t += '}\n';
  t += 'google.script.run.withSuccessHandler(google.script.host.close)\n';
  t += '.returnVal(hd());\n';
  t += '</script>\n';  


  var output = HtmlService.createHtmlOutput(t);
  // output.setSandboxMode(HtmlService.SandboxMode.IFRAME); 
  // SpreadsheetApp.getUi().showModalDialog(output,'please, wait...');
  // output.clear();
  Utilities.sleep(2000);
  return PropertiesService.getScriptProperties().getProperty('ratio');;
}


function returnVal(h) {
  Logger.log(h);
  PropertiesService.getScriptProperties().setProperty('ratio', h);
  return h;
}
Mark
  • 13
  • 1
  • 3
  • You want to retrieve the aspect ratio of image. I understand this. But I cannot understand about ``not put it in a random cell`` and ``doesn't seem to work``. Can I ask you about them? I'm sorry for my poor English skill. – Tanaike Aug 07 '18 at 23:27
  • @Tanaike Thanks for looking in to this. The script that I based this on [here](https://stackoverflow.com/questions/35655010/imageurl-with-specified-height-and-auto-width-to-maintain-aspect-ratio) has a button in the sheet that runs the macro, and the macro will put the ratio in cells B2:B11. I don't want to press a button and put the values in B2:B11, I want the function to just return the value. When I say `doesn't seem to work` I mean that I always get a ratio of 0.0 – Mark Aug 08 '18 at 00:23
  • Thank you for replying. I could understand what you want to do. So I posted an answer. Could you please confirm it? – Tanaike Aug 08 '18 at 01:27

1 Answers1

3

How about this workaround? I think that there are several answers for your situation. So please think of this as one of them. The flow of this script is as follows.

  1. Download the image as a file.
  2. Retrieve imageMediaMetadata from the downloaded file using Drive API.
  3. Delete the downloaded file.
  4. Retrieve the aspect ratio from imageMediaMetadata.

In order to use this sample script, please enable Drive API at Advanced Google Services and API console as follows.

Enable Drive API v2 at Advanced Google Services

  • On script editor
    • Resources -> Advanced Google Services
    • Turn on Drive API v2

Enable Drive API at API console

  • On script editor
    • Resources -> Cloud Platform project
    • View API console
    • At Getting started, click "Explore and enable APIs".
    • At left side, click Library.
    • At Search for APIs & services, input "Drive". And click Drive API.
    • Click Enable button.
    • If API has already been enabled, please don't turn off.

Sample script

function myFunction(url) {
  var blob = UrlFetchApp.fetch(url).getBlob();
  var fileId = DriveApp.createFile(blob).getId();
  var imageMediaMetadata = Drive.Files.get(fileId).imageMediaMetadata;
  var aspectRatio = imageMediaMetadata.width / imageMediaMetadata.height;
  Drive.Files.remove(fileId);
  return aspectRatio;
}

Note :

  • When https://www.theodora.com/flags/e_timor.gif in your question is used for this script, 1.5 is retrieved.

References :

If this was not what you want, I'm sorry.

Added :

If you don't want to create files in Google Drive, you can retrieve the aspect ratio using this library. This library can retrieve the image size from a blob, because the binary data of the image is parsed. When this library is used for your situation, the script becomes as follows.

function myFunction(url) {
  var blob = UrlFetchApp.fetch(url).getBlob();
  var res = ImgApp.getSize(blob);
  var aspectRatio = res.width / res.height;
  return aspectRatio;
}
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thanks for that @Tanaike! I've decided to use the library, and it works perfectly :) – Mark Aug 08 '18 at 02:26
  • @Mark Thank you for replying. I'm glad your issue was solved. I created this library for the situation like this. Thank you, too. – Tanaike Aug 08 '18 at 02:32