【问题标题】:Retrieve binary data / EXIF from image on the page从页面上的图像中检索二进制数据/EXIF
【发布时间】:2014-12-01 12:24:41
【问题描述】:

我需要访问页面上已加载的图像中的EXIF 数据。说,从浏览器扩展。 AFAIU,有一些 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 上已经有similar questions,但没有人回答如何不重新加载图像并访问 EXIF 数据的问题。

我知道我可以在本地将图像保存到 LocalStorage 中,然后使用上面提到的库,但它看起来也有点矫枉过正。

【问题讨论】:

  • 不使用canvas就无法获取EXIF数据客户端,并且canvas受同源策略约束,只能加载本地图像,因此不使用任何一个都无法完成服务器端获取图像,或以某种方式在客户端存储图像以避免同源策略。
  • 我怀疑这一点,但这有点奇怪,因为我总是有机会存储图像和/或重新请求它作为二进制资源。可惜了。
  • 为什么不直接使用 github.com/jseidelin/exif-js 之类的东西?
  • 我不明白为什么您的浏览器扩展不能向服务器发出额外的请求以检索二进制数据?因为只有这样才能得到带有EXIF数据的二进制数据!你的扩展是离线还是什么?

标签: javascript image canvas exif


【解决方案1】:

是否可以访问页面上已加载图像的二进制数据?

不,很遗憾,这是不可能的,不是来自用于图像的原始二进制文件数据。图像处理完毕后,丢弃原始二进制数据。

图像加载过程是一个完全独立的过程,根本不涉及画布——画布在这里是无辜的! :-)

浏览器大致以以下方式加载图像,所有这些都在内部发生,无法从 JavaScript 或 DOM 访问(不一定在所有阶段都按此顺序):

  • 连接到服务器
  • 加载数据以确定文件类型
  • 如果支持的文件类型,加载所有数据
  • 如果支持,则提取 ICC 和 gamma 定义
  • 提取 EXIF 方向/旋转(如果存在)
  • 将文件解压缩/解码为位图
  • 应用 gamma 和 ICC 校正(如果可用且受支持)
  • 使用对位图的内部引用更新 Image 对象
  • 广播load 事件
  • 在任意位置调用onload

当您收到Image 对象时,一切都已准备好并设置好 - 文件的其余部分和从中提取的信息将被丢弃,包括。 EXIF 数据(除了支持它的浏览器中的 EXIF 方向,但是,仅供内部使用,不能从 JavaScript 读取并且仅用于 DOM - 尽管它可能会破坏预期的布局,但通常会被忽略)。我相信大多数浏览器都能够读取此标志,但 AFAIK 只有 Safari 移动版实际使用它(我可能在这里错了,但它不会改变答案的本质)。

只剩下一张带有 RGBA 信息的位图。您现在可以将其插入 DOM 或将其绘制到画布上,但在执行此操作之前元信息已被剥离。当您从画布中提取 data-uri(如 png 或 jpeg,并不重要)时,提取仅基于 canvas 的位图,而不是其上使用的原始图像(图像是除了视频和路径之外,无论如何只是一种图形来源)。

由于目前没有官方API可以从Image对象中访问EXIF数据,所以唯一获取EXIF数据读取的方式就是将图片作为二进制流读取成二进制使用 JavaScript 手动和低级缓冲和提取数据。这就是您列出的库必须这样做的原因。不过缓存可能会来拯救。

这可能不是您所希望的,但我们别无选择,-或- 在服务器端执行此操作(例如在上传时)。然后,您可以提供一种机制来将缓存的 EXIF 数据加载为 JSON 对象或类似的东西。

【讨论】:

  • 有趣!你能添加参考吗?
  • 只是好奇,但我想你知道哪些裁判更适合完善答案。
  • 这是一个绝妙的解释,谢谢。虽然这不是我所希望的,但这绝对可以节省我尝试实现无法实现的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多