1

I am getting stream of information from $http API call. And I use to extract information from it as follows in angular JS,

AngularJS Controller:

ThumbnailsFactory.getThumbnails().then(
  function(res) {
    var FourBytes = 4;
    var TwoBytes = 2;
    var offsetVal = 0;

    var dataView = new DataView(res, offsetVal);
    // 4 bytes for signature
    var sign = dataView.getInt32(offsetVal);
    offsetVal += FourBytes;
    //  2 bytes for UnsupportedVersionException() - must be 1
    var version1 = dataView.getInt16(offsetVal);
    offsetVal += TwoBytes;
    // 2 bytes for ThumbnailMultiStream - must be 1    
    var thumbnailstream = dataView.getInt16(offsetVal);
    offsetVal += TwoBytes;
    //  2 bytes for UnsupportedVersionException() - must be 1        
    var version2 = dataView.getInt16(offsetVal);
    offsetVal += TwoBytes;

    // Total number of images
    var cnt = dataView.getInt32(offsetVal);
    offsetVal += FourBytes;

    // Skip 4 bytes to past the offset vector position.
    offsetVal += FourBytes;

    // Read IDs
    var ids = [];
    for(var i = 0; i < cnt; i++) {
      var id = {
        id: dataView.getInt32(offsetVal),
        img: ""
      };
      ids.push(id);
      offsetVal += FourBytes;    
    }

    // Skip past the offset vector
    for(var i = 0; i < cnt; i++) {
      offsetVal += FourBytes;    
    } 

    // ThumbnailMultiStream
    for(var i = 0; i < cnt; i++) {
      var l = dataView.getInt32(offsetVal);
      offsetVal += FourBytes;  
      var img = "";      
      // Read image data
      for(var j = 0; j < l; ) {
        var read = l - j;
        if(read > 4096) read = 4096;
        img = new DataView(res, offsetVal, read);
        offsetVal += read;

        if(img < 0) {
          // error
          break;
        }
        j += read;
      }

      ids[i].img = "data:image/png;base64," + btoa(img);
      ids[i].buffer = JSON.stringify(img);
    }

    $scope.sign = sign;
    $scope.version1 = version1;
    $scope.thumbnailstream = thumbnailstream;
    $scope.version2 = version2;
    $scope.thumbnails = ids;
  },
  function(error) {
     // error
  }
);

AngularJS Service:

thumbnailsFactory.getThumbnails = function() {
  var deferred = $q.defer();
  var url = "http://192.168.1.61:4321/thumbnails";
  var requestConfig = {
        url: url,
        method: "GET",
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'install_id': 'TiTnMzWAjEK6TbaB2gA55g'
        },
        timeout: 3000,
        responseType: 'arraybuffer'
    };
    $http(requestConfig).then(
        function(res) {
            deferred.resolve(res.data);
        },
        function(error) {
            deferred.reject(error);
        }
    );
    return deferred.promise;       
  }

HTML:

    Sign: {{ sign }}<br>
    Version check 1: {{ version1 }}<br>
    Kind = {{ thumbnailstream }}<br>
    Version check 2: {{ version2 }}<br>      
    Images: <br>

    <div ng-repeat="tn in thumbnails">
        <p> ID: {{ tn.id }} </p>
        <p> Image Buffer: {{ tn.buffer }}</p>
        <img ng-src="{{tn.img}}" alt="Loading...{{ tn.img }}"/>
    </div>

Output:

Sign: 2074848171
version check 1: 1
Kind: 3
version check 2: 1

Images:

    ID: 31
    Buffer: { "byteLength": 557, "buffer": { "byteLength": 2021 },      "byteOffset": 38 }
Loading...data:image/png;base64,W29iamVjdCBEYXRhVmlld10=
    ID: 32
    Buffer: { "byteLength": 1422, "buffer": { "byteLength": 2021 }, "byteOffset": 599 }
Loading...data:image/png;base64,W29iamVjdCBEYXRhVmlld10=

Buffer extraction is correct, as I am getting the next ID of Image correctly while reading buffer. But the problem is I am not getting the PNG image correctly.

How can I get the Image from that Buffer? Please help me guys.

1 Answer 1

1
+50

I think your use of btoa is wrong. You need to extract the string from the dataView.

To do that, everything is here : How to use strings with JavaScript Typed Arrays

I extracted this piece of code for you :

DataView.prototype.getUTF8String = function(offset, length) {
    var utf16 = new ArrayBuffer(length * 2);
    var utf16View = new Uint16Array(utf16);
    for (var i = 0; i < length; ++i) {
        utf16View[i] = this.getUint8(offset + i);
    }
    return String.fromCharCode.apply(null, utf16View);
};

Then, eveything should work fine.

Sign up to request clarification or add additional context in comments.

3 Comments

I hope it works. Can you please elaborate on where and how should I use this method? btoa(img) or btoa(getUTF8String(img)? Thanks in advance.
I think you should just do "data:image/png;base64," + getUTF8String(img) . This should probably work.
I replaced "data:image/png;base64," + btoa(img)" with "data:image/png;base64," + btoa(img.getUTF8String(0, img.byteLength)). And it works fine now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.