Cloudinary - combining upload and fetched images (base64 encoding?)

Hi! I want to use a nice Template column in my Glide sheet to have a lovely image appear. I have a Cloudinary account and am having great fun (now) manipulating images.

BUT I am a bit stuck trying to combine together two images when one or both are external (i.e. needing to use Fetch).

For instance:

  • this is only using Upload (images stored on Cloudinary in my account)

But what I would like to do is have the flexibility to include both stored (Upload) and external (Fetch) images via templates. This would be used, for instance, in the β€˜Ask Card’ screenshot.

I googled about … and this is all I could find (and did not really understand, or could make it practical). Overlay an image that's taken from a fetched public URL – Cloudinary Support

Any tips greatly appreciated! Thanks :slight_smile:


1 Like

I see that there are some threads on base64 encoding (I started from β€˜cloudinary’ and am figuring this out in real time). Ideas for Base64Encode of images - #7 by John_Cabrera

Some things to try, nothing that easy. I might need to rethink my approach!

I’m no expert on cloudinary, but there are several threads by @Robert_Petitto and @Krivo explaining some of it and their use of cloudinary’s fetch command. I’m not sure if it need base64 encoding, or just url encoding, but the Construct URL column will do url encoding I believe.

1 Like

@Mark_Turrell

If you create a google script then you can base64 encode the url to fetch. I put in a function for you to use in a google script

function Encode64ForMe (url) {

      var encodedVar = Utilities.base64EncodeWebSafe(url,Utilities.Charset.UTF_8);

      return encodedVar;

    }

In your google sheet you put in your url to fetch in a cell - e.g.

=Encode64ForMe(β€œhttps://kristianvoigt.dk/SouthAmerica800x600/photos/photo1.jpg”)

Create an url with a overlay which is fetched - it could look something like this

https://res.cloudinary.com/kristianvoigt/image/upload/f_jpg/l_fetch:aHR0cHM6Ly9rcmlzdGlhbnZvaWd0LmRrL1NvdXRoQW1lcmljYTgwMHg2MDAvcGhvdG9zL3Bob3RvMS5qcGc=/image%20carousel/USA.jpg

5 Likes

Magic! Thanks - all working now :slight_smile:

(my next task @Krivo is to make your image carousel :slight_smile: )

@Mark_Turrell all the info should be here :slight_smile:

1 Like

Not sure if yours work in an array, but I have been using this to mimic an arrayformula experience. Hope it helps.

@ThinhDinh That’s is a crazy formula!
Do you think it would be possible in Glide sheet - and would you need Google sheets?

Still needs Google Sheets for this, but hopefully we get a base64 encoding column some time in the future, to combine it with the new URL generator column.

3 Likes

@ThinhDinh That would be nice - wondering when as I suppose core Glide functionality would be first.

1 Like

@Krivo This is awesome! Is there a way to populate this automatically when new information comes in / new rows are created? I imagine it would be a part of the script to watch for new rows?

@mark @jason?

1 Like

@Robert_Petitto Well, I you can include an extra arrayformula in the formula in below link (as @ThinhDinh provided) then I suppose you might be able to do without script. I haven’t been able to do the trick - but arrayformula wizards might :wink:

(just needed to paste this formula as it is crazy :slight_smile:

Please let us know if you get this to work with arrayformula

=CONCATENATE(JOIN(β€œβ€,ARRAYFORMULA(SWITCH(BIN2DEC(TEXT(SPLIT(REGEXREPLACE(CONCATENATE(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8))),REPT(β€œ0”,(FLOOR((LEN(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8))))+(6-1))/6)*6)-LEN(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8)))))),β€œ(.{6})”,β€œ$1/”),β€œ/”),β€œ000000”)),0,β€œA”,1,β€œB”,2,β€œC”,3,β€œD”,4,β€œE”,5,β€œF”,6,β€œG”,7,β€œH”,8,β€œI”,9,β€œJ”,10,β€œK”,11,β€œL”,12,β€œM”,13,β€œN”,14,β€œO”,15,β€œP”,16,β€œQ”,17,β€œR”,18,β€œS”,19,β€œT”,20,β€œU”,21,β€œV”,22,β€œW”,23,β€œX”,24,β€œY”,25,β€œZ”,26,β€œa”,27,β€œb”,28,β€œc”,29,β€œd”,30,β€œe”,31,β€œf”,32,β€œg”,33,β€œh”,34,β€œi”,35,β€œj”,36,β€œk”,37,β€œl”,38,β€œm”,39,β€œn”,40,β€œo”,41,β€œp”,42,β€œq”,43,β€œr”,44,β€œs”,45,β€œt”,46,β€œu”,47,β€œv”,48,β€œw”,49,β€œx”,50,β€œy”,51,β€œz”,52,β€œ0”,53,β€œ1”,54,β€œ2”,55,β€œ3”,56,β€œ4”,57,β€œ5”,58,β€œ6”,59,β€œ7”,60,β€œ8”,61,β€œ9”,62,β€œ-”,63,β€œβ€œ,64,”=β€œ))),REPT(”=β€œ,(FLOOR((LEN(JOIN(β€β€œ,ARRAYFORMULA(SWITCH(BIN2DEC(TEXT(SPLIT(REGEXREPLACE(CONCATENATE(JOIN(β€β€œ,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€β€œ,”(?s)(.{1})β€œ,”$1"&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8))),REPT(β€œ0”,(FLOOR((LEN(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8))))+(6-1))/6)*6)-LEN(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8)))))),β€œ(.{6})”,β€œ$1/”),β€œ/”),β€œ000000”)),0,β€œA”,1,β€œB”,2,β€œC”,3,β€œD”,4,β€œE”,5,β€œF”,6,β€œG”,7,β€œH”,8,β€œI”,9,β€œJ”,10,β€œK”,11,β€œL”,12,β€œM”,13,β€œN”,14,β€œO”,15,β€œP”,16,β€œQ”,17,β€œR”,18,β€œS”,19,β€œT”,20,β€œU”,21,β€œV”,22,β€œW”,23,β€œX”,24,β€œY”,25,β€œZ”,26,β€œa”,27,β€œb”,28,β€œc”,29,β€œd”,30,β€œe”,31,β€œf”,32,β€œg”,33,β€œh”,34,β€œi”,35,β€œj”,36,β€œk”,37,β€œl”,38,β€œm”,39,β€œn”,40,β€œo”,41,β€œp”,42,β€œq”,43,β€œr”,44,β€œs”,45,β€œt”,46,β€œu”,47,β€œv”,48,β€œw”,49,β€œx”,50,β€œy”,51,β€œz”,52,β€œ0”,53,β€œ1”,54,β€œ2”,55,β€œ3”,56,β€œ4”,57,β€œ5”,58,β€œ6”,59,β€œ7”,60,β€œ8”,61,β€œ9”,62,β€œ-”,63,"”,64,β€œ=”))))+(4-1))/4)*4)-LEN(JOIN(β€œβ€,ARRAYFORMULA(SWITCH(BIN2DEC(TEXT(SPLIT(REGEXREPLACE(CONCATENATE(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8))),REPT(β€œ0”,(FLOOR((LEN(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8))))+(6-1))/6)*6)-LEN(JOIN(β€œβ€,ARRAYFORMULA(BASE(UNICODE(SPLIT(REGEXREPLACE(REGEXREPLACE(A2&β€œβ€,β€œ(?s)(.{1})”,β€œ$1”&CHAR(127)),β€œ'”,β€œβ€˜β€™β€),CHAR(127))),2,8)))))),β€œ(.{6})”,β€œ$1/”),β€œ/”),β€œ000000”)),0,β€œA”,1,β€œB”,2,β€œC”,3,β€œD”,4,β€œE”,5,β€œF”,6,β€œG”,7,β€œH”,8,β€œI”,9,β€œJ”,10,β€œK”,11,β€œL”,12,β€œM”,13,β€œN”,14,β€œO”,15,β€œP”,16,β€œQ”,17,β€œR”,18,β€œS”,19,β€œT”,20,β€œU”,21,β€œV”,22,β€œW”,23,β€œX”,24,β€œY”,25,β€œZ”,26,β€œa”,27,β€œb”,28,β€œc”,29,β€œd”,30,β€œe”,31,β€œf”,32,β€œg”,33,β€œh”,34,β€œi”,35,β€œj”,36,β€œk”,37,β€œl”,38,β€œm”,39,β€œn”,40,β€œo”,41,β€œp”,42,β€œq”,43,β€œr”,44,β€œs”,45,β€œt”,46,β€œu”,47,β€œv”,48,β€œw”,49,β€œx”,50,β€œy”,51,β€œz”,52,β€œ0”,53,β€œ1”,54,β€œ2”,55,β€œ3”,56,β€œ4”,57,β€œ5”,58,β€œ6”,59,β€œ7”,60,β€œ8”,61,β€œ9”,62,β€œ-”,63,β€œ_”,64,β€œ=”))))))

Hi @Krivo and @Robert_Petitto, the function in that script provides native arrayformula so you don’t have to use a long arrayformula in the Sheet.

Paste that into a Script and save it.

Then you can easily call it just like below.

image

@ThinhDinh this doesn’t copy down for me:

=base64Encode("{"&char(34)&
"property_name"&char(34)&":"&char(34)&A2:A&char(34)&","&char(34)&
"property_address"&char(34)&":"&char(34)&B2:B&char(34)&","&char(34)&
"propertyid"&char(34)&":"&char(34)&C2:C&char(34)&"
}")

Had to use a helper column

I guess that’s because you wrap text from A, B & C inside the formula, that’s an extra layer so it doesn’t work. Guess the only workaround here is to combine the text first then base64encode it in another column.

@Robert_Petitto @ThinhDinh personally I’m not a fan of custom formulas, especially when used with an arrayformula. I’ve found in the past that these can really start to bog things down. The problem is that every time there is a change in that column, all rows will be recalculated and the custom formula is being called multiple times simultaneously. I’ve seen this situation get so bad that you start getting timeouts and the dreaded β€œ#NA” results.

I think a much better approach would be to take the original function that @Krivo supplied…

…and combine that with an onChange() trigger. Then it only gets called when it is needed, and you avoid all the phaffing around with helper columns and arrayformulas, etc.

I did this recently for @Wiz.Wazeer - converted a custom function to an onChange() trigger - and I think he should attest to the fact that it works much better now.

My two cents :slightly_smiling_face:

3 Likes

Yes, I still remember that dark hour in the middle of the pandemic when I desperately needed help with a custom function that had been running riot on a script of mine.

At the time, I didn’t know what the source of the cause was until @Darren_Murphy took over.

UnFunnily enough, it was a split function that was splitting my script too (don’t ask, how? I don’t want anyone finding out how dumb I am :rofl:)!

@Darren_Murphy got rid of the custom function on the sheet, and fixed the script.

The one thing I knew, but now I know I thought I knew, was that the formula was integral to the script, and it worked for a good couple of months until I noticed occurrences of strange behaviour on the sheet.

Very happy with the outcome.

1 Like