Image to Base64 (no extensions!)

This short guide will show you how to get a base64 string for a local (on your app) image (jpg/png), without using any extensions.

NOTE: Only works for files in Assets

Requirements:

  1. Webviewer, button, (label, canvas)
  2. Provided html file
  3. Images and html file MUST be in the same directory, this example uses app assets.

After conversion, the webviewstring returns:

  1. The filename - as supplied in the webviewstring
  2. The image width in pixels
  3. The image height in pixels
  4. The image file extension (e.g. jpg or png)
  5. The image's base64 string (without the datauri)

These elements are useful for future activities with the base64 string

BLOCKS

HTML

<!DOCTYPE html>
<html>
<body>
   <img id="sourceImage" src="" alt="Source Image">

   <script>
      var wvs = window.AppInventor.getWebViewString();
      var ext = wvs.split('.').pop();
      document.getElementById('sourceImage').src = window.AppInventor.getWebViewString();

      function convertImage() {
         const img = document.getElementById('sourceImage');
         const canvas = document.createElement('canvas');
         const ctx = canvas.getContext('2d');
         canvas.width = img.width;
         canvas.height = img.height;
         ctx.drawImage(img, 0, 0);
         const base64String = canvas.toDataURL('image/' + ext);
         window.AppInventor.setWebViewString(wvs + ", " + img.width + ", " + img.height + ", " + ext + ", " + base64String.replace("data:image/" + ext + ";base64,",""));
      }

      setTimeout(convertImage, 250);

   </script>

</body>
</html>

SCREEN

(example image, orangeSquare.png, has dimensions of 100x100 pixels)

AIA

imgToBase64.aia (3.6 KB)

If you want to convert the base64 string back to a binary file, you can load the image as base64 to a canvas, then canvas saveas to file. You will need to set the canvas dimensions using the width and height, and use the filename supplied from the webviewstring. To get the correct output dimensions for your file you will need the density of your device. See below for more information.

4 Likes

For a camera component output file, where should the two files meet?
Copy the script file to the ASD?

Will depend on android version as to where the camera images are saved, but if the image and the html file can make their way to somewhere in the ASD, then you should be good to go.

Hmmm, having trouble with larger files (timing issue), jpg conversion and running html from ASD, will need to look into it.

You should be able to attach the convertImage function to the image element with a load event that will trigger once the image has been loaded, e.g.,

document.getElementById('sourceImage').addEventListener('load', convertImage);

I have switched to using an img.onload function for larger images which works OK.

<!DOCTYPE html>
<html>
<meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
<head>
	<title>GetImgOnLoadBase64</title>
</head>
<body>
	<script>
         var base64String,canvas,ctx;
	     var img = new Image();
	     img.onload = function() {
         canvas = document.createElement('canvas');
         ctx = canvas.getContext('2d');
         canvas.width = img.width;
         canvas.height = img.height;
         ctx.drawImage(img, 0, 0);
         base64String = canvas.toDataURL('image/png');
	     window.AppInventor.setWebViewString(img.src + ", " + img.width + ", " + img.height + ", " + "png" + ", " + base64String.substring(0, 50));
	     }

  	     img.src = window.AppInventor.getWebViewString();

	</script>
</body>
</html>

However, it seems it is a dead duck when trying to run canvas.toDataURL on an html file loaded from asd using the file:// prefix. CORS policy prevents access to the image, even in the same directory.

Will only work with http://localhost and image files in the assets.

Now if we had an http prefix for the ASD as well... (I know I have asked before...:wink: )

http://asd/...