从页面中检索二进制数据/ EXIF 信息

3
我需要访问已经加载到页面上的图像中的EXIF数据,比如来自浏览器扩展。据我所知,有一些JavaScript方法可以完成这个任务: 前两种方法可能处理本地文件或需要执行额外的(在这种情况下是多余的)请求以检索二进制数据。后者可能起作用:
var canvas = document.createElement("canvas");
canvas.width = oImg.width;
canvas.height = oImg.height;

// Copy the image contents to the canvas
var ctx = canvas.getContext("2d");
ctx.drawImage(oImg, 0, 0);

// Get the data-URL formatted image
var dataURL = window.atob(canvas.toDataURL("image/jpeg", 1.0).split(',')[1]);

但生成的二进制对象不包含EXIF数据0xE1标记),似乎一旦在画布上绘制,它就会产生JFIF(0xE0)标记。

因此,我的问题是:是否有可能访问页面上已加载图像的二进制数据?

请注意:已经有类似的问题在SO上了,但没有一个回答了如何不重新加载图像并获得访问EXIF数据的问题。

我知道我可以将图像保存在本地存储中,然后使用上面提到的库,但这看起来也像是过度处理。


据我所知,没有办法在客户端获取EXIF数据而不使用画布,而画布受同源策略的限制,只能加载本地图像,因此如果不使用服务器端来获取图像或在客户端存储图像以避免同源策略,则无法完成该操作。 - adeneo
我本来就有这个怀疑,但是很奇怪,因为我总是有机会将图像存储或重新请求它作为二进制资源。真是遗憾。 - Mattew Skin
为什么不直接使用 https://github.com/jseidelin/exif-js 这样的东西呢? - rnrneverdies
我不明白为什么你的浏览器扩展无法向服务器发送额外请求以检索二进制数据?因为我们只能通过这种方式获取带有EXIF数据的二进制数据!你的扩展是离线的还是怎么回事? - Bharata
1个回答

3
有没有可能访问已加载到页面上的图像的二进制数据?
不幸的是,这是不可能的,因为在处理完图像后原始的二进制数据会被丢弃。
图像加载过程是一个完全独立的过程,与canvas无关。浏览器大致按照以下方式加载图像(所有阶段都在内部完成,JavaScript或DOM无法访问):
- 连接服务器 - 加载数据以确定文件类型 - 如果支持的文件类型,则加载所有数据 - 提取ICC和伽马定义(如果支持) - 提取EXIF方向/旋转(如果存在) - 将文件解压缩/解码为位图 - 如果可用且支持,则应用伽马和ICC校正 - 更新Image对象,并将内部引用指向位图 - 广播一个load事件 - 调用任何onload函数
当您收到Image对象时,一切都已准备好并设置好了——其余文件和从中提取的信息都被丢弃,包括EXIF数据(例如EXIF方向在支持它的浏览器中可以被读取,但仅供DOM使用,无法从JavaScript中读取,并且通常被忽略,因为它可能会破坏预期的布局)。
只剩下一个具有RGBA信息的位图。现在,您可以将其插入DOM或绘制到canvas上,但在此之前,元信息已被剥离。当您从canvas中提取数据URI(png或jpeg,不太重要)时,提取仅基于canvas的位图,而不是用于它的原始图像(图像只是图形的一个来源,在视频和路径之外还有其他来源)。
由于目前没有官方API可以访问Image对象中的EXIF数据,因此获取读取EXIF数据的唯一方法是将图像作为二进制流读入二进制缓冲区,并使用JavaScript手动和低级别地提取数据。这就是为什么您所列出的库必须以这种方式完成的原因。缓存可能会救援。
这可能不是您所希望的内容,但我们别无选择——或者在服务器端进行处理(例如在上传时)。然后,您可以提供一种机制来将缓存的EXIF数据加载为JSON对象或类似的东西。

1
有趣!你能加上参考资料吗? - rnrneverdies
只是好奇,但我认为您知道哪些参考资料更好地完善答案。 - rnrneverdies
1
这是一个很棒的解释,谢谢。虽然这不是我所希望的,但这绝对节省了我试图实现不可能的事情的时间。 - Aleksei Matiushkin

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