Using SVG "interface" images

This tip is a workaround to solve a problem for which a new feature has been requested.  The feature requests (both for basically the same thing) can be viewed here:

Store content for offline use for specific tables
https://www.googlecloudcommunity.com/gc/Feature-Ideas/Store-content-for-offline-use-for-specific-tab...

Finer-grain control over local image caching
https://www.googlecloudcommunity.com/gc/Feature-Ideas/Finer-grain-control-over-local-image-caching/i...

(Please vote for these if you would like to be able to control caching by table, instead of the current all-or-nothing choice.)

If you are comfortable caching ALL of the images in your app, you may not need this tip.  If, however, you would like to have a small subset of images appear immediately, regardless of your internet connection but, for some reason, cannot or do not want to store all of the images that may be added to your app by users, this tip may help you.

In my case, I use some QuickChart graphs as images in my app but, for some reason, those images cannot be cached and, instead of being skipped on my iPhone, they cause the syncing to get stuck when I have "Store images for offline use" set to "on".  I've reported this issue to AppSheet but it remains unresolved:

https://www.googlecloudcommunity.com/gc/AppSheet-Q-A/Image-loading-gets-stuck/m-p/460685/highlight/t...

(By the way, the syncing didn't just get stuck -- it caused my iPhone to get hot: https://www.googlecloudcommunity.com/gc/AppSheet-Q-A/App-makes-my-iPhone-hot/m-p/447320#M176896)

So, for these reasons, I had to turn "Store images for offline use" off.  This, however, caused a different problem.  When a user is shown the following sort of message, it might take a second or two for the image to show up -- not very cool:

IMG_2504.PNG

I've been wondering if there might not be a workaround for this problem for quite some time now. I finally got the help I needed from this tip written by @SkrOYC :

Easy Icon/Background/Launch image generation with no public URL needed (SVG)
https://www.googlecloudcommunity.com/gc/Tips-Tricks/Easy-Icon-Background-Launch-image-generation-wit...

SkrOYC's tip helped me see that the solution is to put SVG images in your spreadsheet because that way they don't require a URL and display instantly.  It's a bit tedious but if you don't have that many images, it's doable.  Here's my process.

1. Convert png images to svg

I use a free program called Inkscape on my Mac.  I understand it is also available for Windows.  My png images are 600 x 280.  In Inkscape, I set the document to my preferred size (600 x 280), then import my png image, tweak if necessary, and then export as svg.

2. Convert svg to base64 svg

SkrOYC introduced us to this site, which works quite well:  https://base64.guru/converter/encode/image/svg

See his post (https://www.googlecloudcommunity.com/gc/Tips-Tricks/Easy-Icon-Background-Launch-image-generation-wit...) for details.

----------------
Note: When I wrote this tip, I was not aware of @GreenFlux 's SVG Icon Tool, which Converts SVGs to AppSheet format.  To reduce the amount of text you put in your spreadsheet, I have come to the conclusion, thanks to comments by @jyothis_m , @Fabian_Weller  and others, that it is generally preferable to use the SVG Icon Tool to prepare SVG for insertion in a spreadsheet than to use base64.  However, at this writing, I haven't tested to see if it is possible to split the code for large SVG files between cells (next step, explained below) without using base64.
----------------

3. Put base64 svg  code in Google spreadsheet

This can be a bit harder than one might imagine.  If you put the code in a text editor that has a character counting feature, you can check to see if the code is under Google spreadsheet's limit of 50,000 characters.  If you begin by making an original image using a vector graphics editor, you should be OK.  If, however, you have merely converted png images to svg (as I have done), your files may be a good deal over 50,000 characters.

My solution is to split the code into pieces under 50,000 characters each and then paste the pieces into cells in my Google spreadsheet.  Then, in AppSheet, I can put Humpty Dumpty back together again using CONCATENATE() in an image-type virtual column.  Works like a charm!

P.S. Be sure to test carefully in both your browser and in a device or two.  After posting this, I had an experience where a new image I added worked fine in my browser but crashed both my iOS and Android devices.  I still don't know exactly what caused the problem by I suspect that the large SVG files, in combination with an app and data set that was already quite large, caused instability on less powerful devices.  Since then, I have opted to avoid importing raster images (png, jpg, etc.) in favor of using purely svg images, which, of course, are considerably smaller.

 

10 28 3,030
28 REPLIES 28

Thanks to @Ratatosk  for sharing this page to reduce the size (number of characters) of svg files:  https://jakearchibald.github.io/svgomg/

In some cases, you may still exceed the 50,000 character limit and therefore need to split your character sets between cells (as I explained above) but, regardless, smaller is better if there's no perceptible reduction in quality.


@Kirk_Masden wrote:

My solution is to split the code into pieces under 50,000 characters each and then paste the pieces into cells in my Google spreadsheet.  Then, in AppSheet, I can put Humpty Dumpty back together again using CONCATENATE() in an image-type virtual column.  Works like a charm!


This alone might be one of the best Tips and Tricks about SVG base64 encoded images

I consider you my teacher in this area so I'm really honored by your kind comment.  I hope others find this useful.

That's very kind!
Btw, I tend to avoid base64 inside cells because of the length in favor of vector SVG which is the code by itself, like this:

data&colon;image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-package" width="84" height="84" viewBox="0 0 24 24" stroke-width="1.5" stroke="%2341B56D" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
  <polyline points="12 3 20 7.5 20 16.5 12 21 4 16.5 4 7.5 12 3" />
  <line x1="12" y1="12" x2="20" y2="7.5" />
  <line x1="12" y1="12" x2="12" y2="21" />
  <line x1="12" y1="12" x2="4" y2="7.5" />
  <line x1="16" y1="5.25" x2="8" y2="9.75" />
</svg>

 

Interesting.  I tried it but got an error.  I probably made a mistake.  Or, perhaps the particular code of the svg that Inkscape made for me had something in it that caused problems for AppSheet.  At any rate, I think I'll stick with base64 because it's easier for me to use and only about 25% bigger or so with the files I'm using.  I think there's a sense in which base64 may actually be easier for novices, even though it requires an extra step.

This is a great tip! There's somewhat involved up-front setup, but certainly worth it for the use case you outline. I can imagine building a centralized library of images that can be referenced from multiple apps.

Can you clarify a couple points? I wonder whether these are just typos? If not, I don't follow what you're instructing.


@Kirk_Masden wrote:

I make my document in Inkscape that size, import the svg, tweak if necessary, then export as svg.


Do you mean "import the png"?


@Kirk_Masden wrote:

If you begin by making an original imagine using a vector graphics editor, you should be OK.


Do you mean "image" instead of "imagine"? If not, I don't understand.

These are typos + unclear writing.  I thought I had reread what I wrote several times but somehow I missed these.  Thanks!  I'll fix them right away.

First one:

"In Inkscape, I set the document to my preferred size (600 x 280), then import my png image, tweak if necessary, and then export as svg."

Second one:

"If you begin by making an original image using a vector graphics editor, you should be OK."

Thanks for catching these.  I'll try to be more careful.

I'm continuing to reconfigure my app to take advantage of the instant display of images that base64 svg allows despite my inability to utilize the "Store images for offline use" option.  One concern I have is that the data I am putting in one table may make it heavy and hence cause my sync to slow down.  To avoid this, I took advantage of this tip by @jyothis_m :

Disable Delta Sync for particular Tables alone
https://www.googlecloudcommunity.com/gc/Tips-Tricks/Disable-Delta-Sync-for-particular-Tables-alone/m...

I turned on delta sync and then turned it off for all of the tables except the one that stores my base64 svg data (all of my other tables cannot utilize delta sync for one reason or another).

In fact, the idea of making restrictions only apply to certain tables was what got me thinking again about the fundamental problem I addressed in this post.  I'll refrain from trying to explain how one idea wound up leading to another but suffice it to say that @jyothis_m 's post was useful to me in more ways than one.

Happy that you found it useful @Kirk_Masden ๐Ÿ˜Š๐Ÿค


@Kirk_Masden wrote:

I think there's a sense in which base64 may actually be easier for novices


Configure a relational database as a cloud object store - AppSheet Help

Thanks!  I had no idea about this!


@Kirk_Masden wrote:

split the code into pieces under 50,000 characters each and then paste the pieces into cells in my Google spreadsheet.  Then, in AppSheet, I can put Humpty Dumpty back together again using CONCATENATE() in an image-type virtual column.  Works like a charm!


I've been pleased with how I can put even fairly detailed images in my app (at 600 x 280) with this method.  Here's the most detailed one I've put in so far:

Screenshot 2022-12-31 at 10.29.18.png

This one obviously has a lot of detail (hair on the cat and strands in the rope, etc.).  The file I made with the method described above turned about to be a little over 200,000 characters.  So, I needed to split it into five pieces to put in five cells.  Still, my feeling is that five cells should be enough for any kind of illustration I can imagine putting in my app.

One difficulty associated with these SVG images is the lack of previews.  In other words, once I've put the code in the spreadsheet, it's not particularly easy to check to see what images I've put where.  If you feel it is worth your while to work with SVG images in your app, I recommend that you make a second app to view them -- especially if your main app uses the images in many different places and it's hard to check there.  I use importrange and query in Google sheets to make a second spreadsheet for a simple app.  Here's what it looks like:
Screenshot 2023-01-01 at 13.43.39.png

I need to do exactly that. I already have the images in Base64 SVG divided into 3 columns. And in a virtual column, I concatenate those 3 columns and manage to see the image correctly. But what I need is to be able to see that SVG image within another SVG image where I display data from different columns, and I need to dynamically display that other SVG image, do you understand? Have you tried doing that?

Hi @Kirk_Masden thank you very much for this tip. 
I also would use the SVG code. As @SkrOYC mentioned, this has less characters than Base64. You said you got an error. May you share your SVG code? I remember it was tricky to get the SVG working in AppSheet, but with the help of the community we always got them to work ๐Ÿ˜€

Thanks!  I'll look into this and get back to you! ๐Ÿ™‚

Thanks again for your encouragement!

I still can't figure out how to put images that I make with Inkscape in my spreadsheet.  Here's a simple image I made for testing purposes:

https://www2.kumagaku.ac.jp/teacher/~masden/2022/ics/appsheet/red_shape.svg

I tried putting this in my spreadsheet as follows:

 

data&colon;image/svg+xml;utf8,<svg
   width="64"
   height="64"
   viewBox="0 0 16.933333 16.933333"
   version="1.1"
   id="svg663"
   inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
   sodipodi:docname="red_shape.svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <sodipodi:namedview
     id="namedview665"
     pagecolor="#ffffff"
     bordercolor="#000000"
     borderopacity="0.25"
     inkscape:showpageshadow="2"
     inkscape:pageopacity="0.0"
     inkscape:pagecheckerboard="0"
     inkscape:deskcolor="#d1d1d1"
     inkscape:document-units="mm"
     showgrid="false"
     inkscape:zoom="12.660839"
     inkscape:cx="42.058823"
     inkscape:cy="29.776857"
     inkscape:window-width="1728"
     inkscape:window-height="972"
     inkscape:window-x="0"
     inkscape:window-y="38"
     inkscape:window-maximized="0"
     inkscape:current-layer="layer1" />
  <defs
     id="defs660" />
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <path
       style="fill:#ff0000;stroke-width:0.396875;stroke-linejoin:bevel;stroke-miterlimit:0;paint-order:stroke fill markers"
       d="m 3.7273397,4.1452952 c 0,0 0.7184313,9.5637458 4.1275721,9.5306678 3.8246282,-0.03711 4.6989202,-9.5381078 4.6989202,-9.5381078 v 0"
       id="path838"
       sodipodi:nodetypes="cscc" />
  </g>
</svg>

 

In doing so, I'm trying to imitate what I found in the following spreadsheet:
https://docs.google.com/spreadsheets/d/1BqwhxzVTJsiXPhI4MwFqp6-w11gD39G7CWofXRIVRsQ/edit#gid=0
This was made available to us by @GreenFlux (Thanks Greenflux) here:
https://www.googlecloudcommunity.com/gc/Tips-Tricks/SAMPLE-APP-286-SVG-Icons-with-Dynamic-Colors/m-p...

Here's the result:

Screenshot 2023-01-21 at 18.11.42.png

The svgs that don't have error marks are Base64.  I've had no difficulty getting images I've made with Inkscape to appear in my app if I use Base64 (as described above) but have not been successful in trying to take the code out of the svg files and putting that in my sheet.

jyothis_m_0-1674801768350.png

 

โ€ƒDynamic menu by using SVG

I use Flaticon for getting my SVGs and edit them in Boxy if needed to modify the SVG or add a text. 

Then i copy the svg code and paste it in the SVG Covertion App by@GreenFlux 

Finally copy the converted code either in Appsheet VC between two single quote 'svg code' or paste the converted svg code directly in sheet. Its working perfectly. 

Thank you for your help.  I'm going to try to use the links and procedure you shared.

Success!!! Thank you!  @GreenFlux's SVG conversion app is great!!!!!  Thanks!!  This will allow me to reduce the size of the images I store in my spreadsheet (I won't need to use Base64 after all).

Posting a sample svg code converted for appsheet use 

 

Screenshot_2023-01-21-23-10-36-699_x1Trackmaster.x1Trackmaster.jpg

โ€ƒ

 

I also made a test app for converting the SVG code to appsheet svg code and with all different view types to see how the svg looks in different views

Screenshot_2023-01-21-23-08-15-971_x1Trackmaster.x1Trackmaster.jpg

โ€ƒ

Screenshot_2023-01-21-23-08-11-126_x1Trackmaster.x1Trackmaster.jpg

โ€ƒ

Screenshot_2023-01-21-23-08-05-697_x1Trackmaster.x1Trackmaster.jpg

โ€ƒ

Screenshot_2023-01-21-23-08-03-740_x1Trackmaster.x1Trackmaster.jpg

โ€ƒ

 

IMG_20230125_180109.jpg

Another example of how useful this SVG tip has been for me

Very cool!!!  Could you share how you did it?  Perhaps you could write a separate "Tip" post, if it's not too much trouble.

Sure, will do that ๐Ÿ‘

Would it be possible to do this with SVG code exported from adobe XD? If so would tgere be ways to accommodate component states?

Top Labels in this Space