如何在AngularJS中从$http.get返回图像

23
在我的控制器中,我调用了一个返回 Promise 的服务。
var onComplete = function(data) {
               $scope.myImage = data;           
            };

在我的服务中,我通过直接传递图像的URL来调用获取图像的功能:

   return $http.get("http://someurl.com/someimagepath")
         .then(function(response){          
          return response.data;
         });

所有的调用都成功了,response.data似乎保存在一个图像中:

����JFIF��;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90
��C




��C      

����"�� 
���}!1AQa"q2���#B��R��$

虽然我不确定它是否有效,因为我无法显示它。我已经尝试过(在index.html中)

 <img ng-src="{{myImage}}"> 
  and
<img ng-src="{{myImage}}.jpeg"> 
  and   
 <img ng-src="data:image/JPEG;base64,{{myImage}}">

有什么想法吗? 是否可能从$http.get返回实际图像并将其响应转换回图像(jpeg等)?

谢谢!


根据我的实验,尝试将图像注入标签以减少我正在制作的单页Angular应用程序的HTTP请求,不,这是不可能的。 - RevanProdigalKnight
1
这里的最终目标是什么?如果您知道 http://someurl.com/someimagepath,为什么需要通过 $http.get() 下载它,然后将其注入到 src 标签中,而不是直接将路径放在 src 标签中并跳过中间环节? - Tom
1
@Tom - 这只是一个异步检索一些数据的测试,我想用它来检索一张图片。除了学习AngularJS之外,没有真正的目标。 - ra170
你能帮我看一下这个问题吗?我遇到了类似的问题:https://stackoverflow.com/questions/47161442/render-blob-image-with-angular-4 - Hanzo
这个答案对我真的很有用 https://stackoverflow.com/a/33125433/4631539 - parand87
4个回答

37

似乎没有任何方法是完整的,这是一个完整的解决方案:

  $http({
    method: 'GET',
    url: imageUrl,
    responseType: 'arraybuffer'
  }).then(function(response) {
    console.log(response);
    var str = _arrayBufferToBase64(response.data);
    console.log(str);
    // str is base64 encoded.
  }, function(response) {
    console.error('error in getting static img.');
  });


  function _arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
  }

然后我就可以直接使用它:

<img data-ng-src="data:image/png;base64,{{img}}">

arraybuffer转换为base64的函数直接取自ArrayBuffer to base64 encoded string


这篇文章的情景与我的情况非常相似。我喜欢这个解决方案的潜力,但不幸的是我不喜欢通过 Angular 的 $http 服务传递回来的二进制数据(字节数组)的结构或格式。当尝试创建字节数组时,Uint8Array 返回为空。一旦我弄清楚了区别,我会发布我的解决方案。 - Michael M
你救了我的一天..!! 谢谢。@paradite 我可以知道如何检索图像列表并显示吗? - Hema
成功了!!有人给这个家伙颁个奖章吧!!对于未来的读者们,在$http中使用responseType: 'arraybuffer'是非常重要的,请不要忽略它。我曾试图在没有它的情况下完成任务,但却无法实现。如果没有它,_arrayBufferToBase64似乎会返回空字符串。 - Pramesh Bajracharya

18

万一有人需要的话。

在我的情况下,我不得不通过Angular的$http服务发送请求,因为我们还要进行各种转换和其他花哨的操作。

所以基于之前提到的Mozilla指南,我想出了以下解决方案:

let getImageDataURL = (url, imageType = 'image/jpeg') => {
  return $http.get(url, {responseType: 'arraybuffer'}).then((res) => {
    let blob = new Blob([res.data], {type: imageType});
    return (window.URL || window.webkitURL).createObjectURL(blob);
  });
};
基本思路是设置底层XHR请求的responseType属性,并将二进制内容转换为数据URL。

7
返回结果:

所返回的图像采用二进制编码,而不是Base64。

可以理解的是,<img> 标签不支持通过属性从二进制源获取,因此您需要考虑其他解决方案。

您可以尝试使用TypedArraysbtoa函数在客户端将二进制编码转换为Base64。然后您就能够使用

<img ng-src="data:image/JPEG;base64,{{myImage}}">

这篇指南由Mozilla编写,介绍了如何发起XHR请求并将图像直接读入UInt8Array。它应该是一个很好的起点。

它是为普通的Javascript编写的,但如果您刚学习Angular,则将其翻译成Angular应该是一个不错的练习。


谢谢,看起来确实是一个二进制字符串。我会查看指南的! - ra170
1
@ra170,如果您已经解决了这个问题,能否发布一下代码? - Tometoyou
@Tometoyou通过谷歌搜索找到了解决方案:arraybuffer转换为base64:https://dev59.com/fWw05IYBdhLWcg3w41wp - paradite
你能帮我看一下这个问题吗?我遇到了类似的问题:https://stackoverflow.com/questions/47161442/render-blob-image-with-angular-4 - Hanzo

1
通过https://dev59.com/fVgQ5IYBdhLWcg3wRR1j#43032560,您可以使用“blob”作为responseType,并使用FileReader非常简洁地获取数据URL。
$http.get( url, { responseType: "blob" } ).then((result) => {
  var reader = new FileReader();
  reader.readAsDataURL( result.data );
  reader.onload = function (e) {
    return e.target.result;
  };
});

您可以这样引用它:

<img data-ng-src="{{img}}">

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接