3

说我有一个<img/>. 这个img有src='http://somelocation/getmypic'。稍后,我可能想根据接收二进制数据的 ajax 调用更改 img 的内容。我只有在收到 ajax 回调中的数据后才知道是否要将其应用于图像。我可能决定不这样做。

据我从我所做的研究中可以看出,在 img 上设置二进制数据的唯一方法是通过 base64 编码二进制数据并将 img src 设置为生成的 base 64 编码字符串。

我的第一个也是主要问题是:开销是多少?这是否意味着我将图像下载的处理和内存使用量增加了两倍?我的ajax回调获取已加载到内存中的二进制数据,然后我对二进制流进行base 64编码,然后(我假设)浏览器将此流解码回二进制?还是我错过了什么,实际上并没有那么糟糕?

我的第二个问题是:为什么没有base64编码就无法将二进制数据直接设置到img中?我使用的大多数 UI 语言都允许您将图像从文件加载到“PictureBox”(例如)中,并在“PictureBox”中绘制。为什么img不允许这样做?我在想 img.binary=bytes 会将 src 设置为“二进制”或类似的东西。看起来这个功能在 img 和 canvas 之间是分开的,但有时你想两者都做。我只是想知道我的理解是否遗漏了一些东西(例如,不允许在 img 上直接设置二进制数据有一些设计或实现的好处)。

谢谢你。

4

1 回答 1

2

嗯,这就是我想出的。我不确定性能或内存使用情况如何,但它比 base64 编码容易得多,并且可以与 asp.net MVC FileStreamResult 一起使用。所以,我想我会把它贴在这里,以防它帮助别人:

 var oReq = new XMLHttpRequest();
    oReq.open("post", '/somelocation/getmypic', true );        
    oReq.responseType = "blob";
    oReq.onload = function ( oEvent )
    {
        var blob = oReq.response;
        var imgSrc = URL.createObjectURL( blob );                        
        var $img = $( '<img/>', {                
            "alt": "test image",
            "src": imgSrc
        } ).appendTo( $( '#bb_theImageContainer' ) );
        window.URL.revokeObjectURL( imgSrc );
    };
    oReq.send( null );

其基本思想是数据不会被篡改,而是以 blob 形式接收。为该 blob 构造了一个 url(我认为这实质上意味着您可以使用 URL 来访问内存中的该 blob)。但好处是您可以将 img src 设置为此,这……太棒了。

这个答案让我走上了正确的轨道,然后是这个页面和mdn 上的这个页面。注意支持的浏览器。

于 2013-10-30T11:16:39.613 回答