Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用来自ajax的原始图像数据请求数据URI_Javascript_Ajax_Image_Base64 - Fatal编程技术网

Javascript 使用来自ajax的原始图像数据请求数据URI

Javascript 使用来自ajax的原始图像数据请求数据URI,javascript,ajax,image,base64,Javascript,Ajax,Image,Base64,我尝试使用Ajax和数据URI的组合来加载JPEG图像,并通过一个HTTP请求提取其EXIF数据。我正在修改一个库()来实现这一点;目前,该库使用两个HTTP请求来设置映像的源和获取EXIF数据 让EXIF工作,没问题。但是,我很难使用来自ajax请求的原始数据作为图像的源 技术小型测试的源代码: <!DOCTYPE html> <html> <head> <script type='text/javascript'> function init

我尝试使用Ajax和数据URI的组合来加载JPEG图像,并通过一个HTTP请求提取其EXIF数据。我正在修改一个库()来实现这一点;目前,该库使用两个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>

函数init()
{
//拥有ajax库-使用它请求测试jpg图像
新建Ajax().sendRequest
(
“/images/photos/badger.jpg”,
{方法:“获取”,
回调:函数(xmlHTTP)
{
var encoded=btoa(unescape(encodeURIComponent(xmlHTTP.responseText));
var dataURL=“数据:图像/jpeg;base64,”+编码;
document.getElementById(“image”).src=dataURL;
}
}
);
}
我使用此mozilla页面获取有关base64编码/解码的信息:

你知道哪里不对吗?环顾四周,我可以创建base64编码的图像服务器端,但它可以像这样在客户端完成吗?首先,base64编码服务器端明显增加了数据大小,而此练习的全部目的是减少从服务器传输的数据量以及请求数

谢谢,
Nick

您必须在服务器端进行base64编码,因为responseText被视为字符串,服务器发送的响应数据是二进制的

谢谢你。我对此做了更多的挖掘,结果发现至少在当前版本的Firefox和Chrome上有一个解决方案(编辑: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>

函数init()
{
var xmlHTTP=new XMLHttpRequest();
open('GET','/images/photos/badger.jpg',true);
//必须包含此行-指定所需的响应类型
xmlHTTP.responseType='arraybuffer';
xmlHTTP.onload=函数(e)
{
var arr=新的Uint8Array(this.response);
//将int数组转换为二进制字符串
//转换*数组时必须使用apply()*
//fromCharCode()接受一个或多个单个值,而不是
//数组。
var raw=String.fromCharCode.apply(null,arr);
//这很有效!!!
var b64=btoa(原始);
var dataURL=“数据:图像/jpeg;base64,”+b64;
document.getElementById(“image”).src=dataURL;
};
xmlHTTP.send();
}
基本上,您需要一个二进制响应,然后创建数据的8位无符号int视图,然后再将其转换回(二进制友好的)字符串。fromCharCode()。应用是必需的,因为String.fromCharCode()不接受数组参数。然后使用btoa(),创建数据url,然后它就可以工作了

以下资源对此很有用:


尼克的回答很有效。但是,当我用一个相当大的文件执行此操作时,我得到了一个堆栈溢出

var raw = String.fromCharCode.apply(null,arr);
在块中生成原始字符串对我来说很好

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);
}
var raw='';
变量i,j,子数组,区块=5000;

对于(i=0,j=arr.length;i我在上面描述的
ArrayBuffer->String->Base64
方法中遇到了问题,但遇到了另一种使用该方法的方法,效果非常好。这不是将原始数据转换为Base 64的方法(如标题所示),而是显示原始图像数据的一种方法(如实际问题所示):


所有的功劳都归功于Jan Miksovsky,他的作者。我只是偶然发现了它,并认为它会对本次讨论作出有益的补充。

我已经为此问题工作了两天,因为我需要一个解决方案来根据从Microsoft Graft收到的原始数据呈现用户的Outlook配置文件图片。我已经实现了上述所有解决方案,但没有成功。然后我找到了这个git:

在我的例子中,我只是将
“data:image/png;base64”
替换为
“data:image/jpg;base64”


它就像一个魔咒。

现代ES6图像下载解决方案:(不指定图像类型)


我做了更多的挖掘,结果发现有一个解决方案,至少在现代HTML5浏览器中(适用于当前的Firefox/Chrome)。此外,为了支持IE9,您必须在此项目中包含typedarray.js。这定义了Uint8Array。这是使其在iOS和Android上工作所必需的技巧。感谢您发布这篇文章!很棒的帖子。我现在终于可以发表评论了,但如果您因为文件太大而遇到堆栈溢出错误,请参阅下面的答案!做得好!我已经完成了要做一些测试,但现在,这对我来说很有吸引力!除此之外,如果您右键单击在另一个选项卡中打开文件,与ArrayBuffer->String->Base64方法相比,您没有这么长的URL。(顺便说一句:“webkitURL”已被弃用。请改用“URL”)
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();
async function downloadImageFromUrl(url) {    // returns dataURL
  const xmlHTTP = new XMLHttpRequest();
  xmlHTTP.open('GET', url, true);
  xmlHTTP.responseType = 'blob';
  const imageBlob = await new Promise((resolve, reject) => {
    xmlHTTP.onload = e => xmlHTTP.status >= 200 && xmlHTTP.status < 300 && xmlHTTP.response.type.startsWith('image/') ? resolve(xmlHTTP.response) : reject(Error(`wrong status or type: ${xmlHTTP.status}/${xmlHTTP.response.type}`));
    xmlHTTP.onerror = reject;
    xmlHTTP.send();
  });
  return blobToDataUrl(imageBlob);
}

function blobToDataUrl(blob) { return new Promise(resolve => {
  const reader = new FileReader();    // https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
  reader.onload = e => resolve(e.target.result);
  reader.readAsDataURL(blob);
})}
downloadImageFromUrl('https://a.b/img.png').then(console.log, console.error)