AngularJS - 显示从 $http 调用接收到的缓冲区中的多个 PNG 图像

AngularJS - Displaying multiple PNG images from buffer received from $http call

我正在从 $http API 调用中获取信息流。我用 angular JS,

从中提取信息如下

AngularJS 控制器:

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 服务:

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>

输出:

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=

缓冲区提取是正确的,因为我在读取缓冲区时正确获取了图像的下一个 ID。但问题是我没有正确获取 PNG 图像。

如何从该缓冲区中获取图像?请大家帮帮我。

我认为你对btoa的使用是错误的。您需要从数据视图中提取字符串。

要做到这一点,一切都在这里:How to use strings with JavaScript Typed Arrays

我为您提取了这段代码:

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);
};

然后,一切都应该正常工作。