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.
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.