nic*_*ckw 36 javascript ajax base64 image
我正在尝试使用Ajax和数据URI的组合来加载JPEG图像并使用单个HTTP请求提取其EXIF数据.我正在修改一个库(https://github.com/kennydude/photosphere)来做这件事; 目前,此库使用两个HTTP请求来设置图像源并获取EXIF数据.
获得EXIF工作,没问题.但是,我很难将ajax请求中的原始数据用作图像的源.
对该技术进行小规模测试的源代码:
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
function init()
{
    // own ajax library - using it to request a test jpg image
    new Ajax().sendRequest
    (
        "/images/photos/badger.jpg",
         { method : "GET",
            callback: function(xmlHTTP)
            {
                var encoded = btoa (unescape(encodeURIComponent(xmlHTTP.responseText)));
                var dataURL="data:image/jpeg;base64,"+encoded;
                document.getElementById("image").src = dataURL;
            }
        }
    );
}
</script>
<script type="text/javascript" src="http://www.free-map.org.uk/0.6/js/lib/Ajax.js"></script>
</head>
<body onload='init()'>
<img id="image" alt="data url loaded image" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我得到了看起来像发回的合理的jpeg数据,原始数据的长度(以字节为单位)和base64编码然后未编码的原始数据是相同的.但是,在Firefox(25)和Chrome(31)(当前版本)上设置图像src的尝试失败 - chrome显示"损坏的图像"图标,表明src是无效格式.
我使用这个mozilla页面获取有关base64编码/解码的信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
知道什么可能是错的吗?环顾四周我可以创建base64编码的图像服务器端,但它可以像这样在客户端完成吗?首先,base64编码服务器端显然增加了数据大小,本练习的目的是减少从服务器传输的数据量以及请求数.
谢谢,尼克
nic*_*ckw 33
感谢那.我已经对此进行了更多的挖掘,结果发现至少在当前版本的Firefox和Chrome上有一个解决方案(EDIT:IE10也可以).您可以使用XMLHttpRequest2并使用类型化数组(Uint8Array).以下代码有效:
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
function init()
{
    var xmlHTTP = new XMLHttpRequest();
    xmlHTTP.open('GET','/images/photos/badger.jpg',true);
    // Must include this line - specifies the response type we want
    xmlHTTP.responseType = 'arraybuffer';
    xmlHTTP.onload = function(e)
    {
        var arr = new Uint8Array(this.response);
        // Convert the int array to a binary string
        // We have to use apply() as we are converting an *array*
        // and String.fromCharCode() takes one or more single values, not
        // an array.
        var raw = String.fromCharCode.apply(null,arr);
        // This works!!!
        var b64=btoa(raw);
        var dataURL="data:image/jpeg;base64,"+b64;
        document.getElementById("image").src = dataURL;
    };
    xmlHTTP.send();
}
</script>
</head>
<body onload='init()'>
<img id="image" alt="data url loaded image" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
基本上你要求二进制响应,然后在将数据转换回(二进制友好)字符串String.fromCharCode()之前创建数据的8位无符号int视图.apply是必要的,因为String.fromCharCode()不接受数组参数.然后你使用btoa(),创建你的数据网址然后它工作.
以下资源对此非常有用:
和
http://www.html5rocks.com/en/tutorials/file/xhr2/
缺口
Roc*_*coB 18
尼克的回答非常有效.但是当我用一个相当大的文件执行此操作时,我得到了堆栈溢出
var raw = String.fromCharCode.apply(null,arr);
Run Code Online (Sandbox Code Playgroud)
以块的形式生成原始字符串对我来说效果很好.
var raw = '';
var i,j,subArray,chunk = 5000;
for (i=0,j=arr.length; i<j; i+=chunk) {
   subArray = arr.subarray(i,i+chunk);
   raw += String.fromCharCode.apply(null, subArray);
}
Run Code Online (Sandbox Code Playgroud)
        Xav*_*olt 15
我遇到了上述ArrayBuffer -> String -> Base64方法的问题,但是使用Blob运行的另一种方法效果很好.它不是将原始数据转换为Base 64的方法(如标题中所示),但它是一种显示原始图像数据的方法(如实际问题中所示):
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
    var blb = new Blob([xhr.response], {type: 'image/png'});
    var url = (window.URL || window.webkitURL).createObjectURL(blb);
    image.src = url;
}
xhr.open('GET', 'http://whatever.com/wherever');
xhr.send();
Run Code Online (Sandbox Code Playgroud)
所有的功劳都归功于这个小提琴手的作者Jan Miksovsky .我偶然发现了它并认为这对这次讨论有用.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           50267 次  |  
        
|   最近记录:  |