1

I'm trying to embed an image using the base64 data pattern, instead of a URL reference. I first download the data from Azure Blob storage, using the Azure Node.js SDK:

https://azure.microsoft.com/en-us/documentation/articles/storage-nodejs-how-to-use-blob-storage/#download-blobs

From what I can tell the data downloads as a string. But I'm not sure what to do with the string to get it into base64.

I need to encode the data as base64 and set the image source attribute. How do I do that?

Here is a snippet that shows what happens when I try to just embed the downloaded data directly:

        cameraContainer.listBlobsSegmentedWithPrefix($routeParams.cameraId, path, null, options, function(error, result, response) {
        result.entries.forEach(function(entry) {
            $http.get(containerUrl + "/" + $routeParams.cameraId + "/" + entry.name + containerToken)
                .then(function(successResponse) {
                    $scope.camera.imageUrl = "data:image/jpeg;base64," + successResponse.data;
                }, function(errorResponse) {

                });
        });
    });

I end up getting this error in the browser:

enter image description here

Also, if I try executing the following JS:

console.log(decodeURIComponent(successResponse.data));

I get this error:

enter image description here

Here is the raw data when logging to console

Paul Fryer
  • 9,268
  • 14
  • 61
  • 93
  • _"From what I can tell the data downloads as a string"_ Is the data already a `base64` string? Can you include downloaded data string at Question? – guest271314 Sep 06 '16 at 00:32
  • I added a code snippet and error screenshot to show more specifically what I'm seeing from Javascript. – Paul Fryer Sep 06 '16 at 00:40
  • What does `console.log(decodeURIComponent(successResponse.data))` log at `console`? – guest271314 Sep 06 '16 at 00:42
  • Looks like the decodeURIComponent function doesn't recognize that format as a URL - see updated screenshots. Also, something I noticed is that the image is downloading as gzip encoding. Do you think I need first Decompress it? – Paul Fryer Sep 06 '16 at 00:49
  • Is there an option to set `successResponse.data` to a `Blob` instead of an encoded string? – guest271314 Sep 06 '16 at 00:54
  • I'm not sure. I'm using Angular JS, the $http docs talk about a "Transforming Requests and Responses". Is that what your talking about? https://docs.angularjs.org/api/ng/service/$http – Paul Fryer Sep 06 '16 at 01:02
  • Can you include the full `successResponse.data` string at as text Question? Cannot view entire string at image currently posted at Question – guest271314 Sep 06 '16 at 01:06
  • I added a log of console output. It was too much data for the post, so I uploaded a file you can download, see link at end of post. – Paul Fryer Sep 06 '16 at 01:21
  • You're getting back binary data. I believe you would need to convert that into base64 string. – Gaurav Mantri Sep 06 '16 at 03:32
  • Could you provide the code snippet in your Node.js side which to show how to download the blobs and respond for your client side? – Gary Liu Sep 06 '16 at 05:39
  • @GauravMantri that's what I need some help with, how do I convert the binary data to base64 in Javascript? – Paul Fryer Sep 06 '16 at 17:26
  • Added an answer with the code that we're using for doing exact same thing (downloading blob via JS and displaying them inline). Give it a try. HTH. – Gaurav Mantri Sep 06 '16 at 17:37
  • I found the solution here: http://stackoverflow.com/questions/23013871/how-to-parse-into-base64-string-the-binary-image-from-response – Paul Fryer Sep 10 '16 at 01:53

1 Answers1

0

This is how I did it in our product. Please give it a try.

Essentially the data you're getting back is Uint8Array. First thing you would need to do is convert that array into string. You can use the following code to do so:

function Uint8ToString(array) {
    var chunkSize = 0x8000;
    var c = [];
    for (var i = 0; i < array.length; i += chunkSize) {
        c.push(String.fromCharCode.apply(null, array.subarray(i, i + chunkSize)));
    }
    return c.join('');
}

Next, you need to convert this string in base64 format. Here's how I'm doing it currently:

var blobContentsAsString = Uint8ToString(blobContents); 
var blobContentsAsBase64String = btoa(blobContentsAsString);
$scope.camera.imageUrl = "data:image/jpeg;base64," + blobContentsAsBase64String;

Do give it a try.

Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241