使用来自 ajax 请求的原始图像数据获取数据 URI [英] Using raw image data from ajax request for data URI

查看:33
本文介绍了使用来自 ajax 请求的原始图像数据获取数据 URI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Ajax 和数据 URI 的组合来加载 JPEG 图像并通过单个 HTTP 请求提取其 EXIF 数据.我正在修改一个库(https://github.com/kennydude/photosphere)来做到这一点;目前这个库使用两个 HTTP 请求来设置图像的来源和获取 EXIF 数据.

I'm trying to use a combination of Ajax and data URIs to load a JPEG image and extract its EXIF data with a single HTTP request. I am modifying a library (https://github.com/kennydude/photosphere) to do this; currently this library uses two HTTP requests to set the source of the image and to get the EXIF data.

让 EXIF 正常工作,没问题.但是,我在使用来自 ajax 请求的原始数据作为图像源时遇到了困难.

Getting the EXIF works, no problem. However I am having difficulty using the raw data from the ajax request as source for the image.

该技术的小测试的源代码:

Source code for a small test of the technique:

<!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>

我得到看起来像发回的合理 jpeg 数据,原始数据的长度(以字节为单位)和 base64 编码然后未编码的原始数据是相同的.但是,在 Firefox (25) 和 Chrome (31)(当前版本)上设置图像 src 的尝试均失败 - chrome 显示损坏的图像"图标,表明 src 格式无效.

I get what looks like sensible jpeg data sent back, and the length (in bytes) of the raw data and the base64-encoded-then-unencoded-again raw data is the same. However the attempt to set the image src fails on both Firefox (25) and Chrome (31) (current versions) - chrome displays "broken image" icon suggesting the src is an invalid format.

我使用此 mozilla 页面获取有关 base64 编码/解码的信息:

I used this mozilla page for info on base64 encoding/decoding:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding

知道哪里出了问题吗?环顾四周,我可以创建 base64 编码的图像服务器端,但可以像这样在客户端完成吗?一方面,base64编码服务器端明显增加了数据量,本练习的全部目的是减少从服务器传输的数据量,以及请求的数量.

Any idea what might be wrong? Looking around I can create the base64 encoded image server side but can it be done client side like this? For one thing, base64 encoding server side obviously increases the data size and the whole purpose of this exercise is to cut down the amount of data being transferred from the server, as well as the number of requests.

谢谢,尼克

推荐答案

谢谢.我对此进行了更多的挖掘,结果证明至少在当前版本的 Firefox 和 Chrome 上有一个解决方案(IE10 也可以).您可以使用 XMLHttpRequest2 并使用类型化数组 (Uint8Array).以下代码有效:

Thanks for that. I've done a bit more digging on this and it turns out there is a solution at least on current versions of Firefox and Chrome ( IE10 works too). You can use XMLHttpRequest2 and use a typed array (Uint8Array). The following code works:

<!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>

基本上你要求一个二进制响应,然后在将数据转换回(二进制友好的)字符串 String.fromCharCode() 之前创建一个 8 位 unsigned int 数据视图.apply 是必要的,因为 String.fromCharCode() 不接受数组参数.然后你使用 btoa(),创建你的数据 url,然后它就可以工作了.

Basically you ask for a binary response, then create an 8-bit unsigned int view of the data before converting it back into a (binary-friendly) string String.fromCharCode(). The apply is necessary as String.fromCharCode() does not accept an array argument. You then use btoa(), create your data url and it then works.

以下资源对此很有用:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays?redirectlocale=en-US&redirectslug=JavaScript%2FTyped_arrays

http://www.html5rocks.com/en/tutorials/file/xhr2/

尼克

这篇关于使用来自 ajax 请求的原始图像数据获取数据 URI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆