从页面上的图像中检索二进制数据/ EXIF

时间:2014-11-25 09:55:28

标签: javascript image canvas exif

我需要访问已在页面上加载的图片中的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中,然后使用上面提到的库,但它看起来也有点矫枉过正。

1 个答案:

答案 0 :(得分:3)

  

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

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

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

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

  • 连接服务器
  • 加载数据以确定文件类型
  • 如果支持的文件类型,则加载所有数据
  • 如果支持,则提取ICC和gamma定义
  • 提取EXIF方向/轮换(如果有)
  • 将文件解压缩/解码为位图
  • 如果可用且支持,则应用gamma和ICC更正
  • 使用对位图的内部引用
  • 更新Image对象
  • 广播load活动
  • 在任何
  • 中调用onload来电

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

RGBA信息只剩下一个位图。您现在可以将其插入DOM或将其绘制到画布上,但在执行此操作之前已删除元信息。当您从画布中提取数据时(如png或jpeg,并不重要),提取仅基于画布的位图,而不是其上使用的原始图像(图像是除了视频和路径之外,只需要一个图形来源。

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

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