JavaScript:我可以从文件上传输入中读取EXIF数据吗?

时间:2011-04-25 23:43:21

标签: javascript jquery image exif

我有以下任务:

  • 提供<input type=file />
  • 当用户添加文件时:
    • 阅读EXIF数据(特别是位置信息,如果有)
    • 使用Ajax
    • 将文件和EXIF信息发送到外部API

因此,当文件添加到input时,我想使用JavaScript来提取一些EXIF数据。

这可能吗?

我知道这个问题:Can I read Exif data of a picture in the client-side with js?,它指的是http://blog.nihilogic.dk/2008/05/reading-exif-data-with-javascript.html

但我的问题是(我认为?)略有不同 - 我想在图像甚至在我的域上之前提取EXIF数据,而它是在用户的本地文件系统上,如果你看到我的意思。我可以访问二进制数据,所以我也可以获得EXIF吗?

感谢您的建议。

6 个答案:

答案 0 :(得分:7)

您可以使用HTML5在客户端上执行此操作。对于不支持File和FileReader的旧浏览器,您应该有适当的基于服务器的回退。

您可以编写自己的exif解析器或使用jsjpegmeta library(Ben Leslie),这是一个简单的+非常棒的库,可让浏览器从大多数jpeg文件中提取EXIF数据。有a patch表示它修复了大多数兼容性问题。我没有测试过补丁,但是准备好分叉项目并戴上你的github帽子。

获取EXIF:

  1. 打开文件对话框:我通常会创建一个按钮来调用函数来生成<file输入并添加更改处理程序
  2. 获取文件:在文件更改处理程序ue $(this).get(0).files中获取所选文件的列表。
  3. 解析exif数据:将浏览结果发送给jsjpegmeta
  4. 我不得不稍微调整一下库以使它做我想要的(我想要一个commonJS库)我也在问题1中确定了调整。

    Here is a fiddle

答案 1 :(得分:1)

Shanimal的回答是正确的,但它永远不会让我感到惊讶的是人们如何制造复杂的事物。如果您不需要支持多个文件上传,那么jsjpegmeta库的实现可以完成同样的任务:

<input type="file" accept="image/jpeg" id="input" />
<script src="./jsjpegmeta.js"></script>
<script>
document.getElementById('input').onchange = function(e) {
  var file = e.target.files[0],
    fr = new FileReader();
  fr.onloadend = function() {
    console.log(new JpegMeta.JpegFile(this.result, file.name));
  };
  fr.readAsBinaryString(file);
};
</script>

答案 2 :(得分:0)

是的,使用现代浏览器,您可以读取文件内容,因此提取exif。你展示的链接就是一个例子。问题是在旧浏览器IE6-9,FF 3.6-这是不可能的。此外,您应该考虑浏览器从大文件中读取和提取exif是一个艰难的过程。

答案 3 :(得分:0)

我知道这可能已经解决了,但我想为人们在这个问题上绊脚石提供另一种解决方案。

有一个新的库exifr,您可以使用它来完成此操作。它是维护,积极开发的,注重性能的库,可在nodejs和浏览器中使用。

从一个文件中提取exif的简单示例:

document.querySelector('#filepicker').addEventListener('change', async e => {
  let file = e.target.files[0]
  let exifData = await exif.parse(file)
  console.log('exifData', exifData)
})

从多个文件中提取exif的复杂示例:

document.querySelector('#filepicker').addEventListener('change', async e => {
    let files = Array.from(e.target.files)
    let promises = files.map(exif.parse)
    let exifs = await Promise.all(promises)
    let dates = exifs.map(exif => exif.DateTimeOriginal.toGMTString())
    console.log(`${files.length} photos taken on:`, dates)
})

您甚至可以提取文件中嵌入的缩略图:

let img = document.querySelector("#thumb")
document.querySelector('input[type="file"]').addEventListener('change', async e => {
  let file = e.target.files[0]
  img.src = await exifr.thumbnailUrl(file)
})

您还可以尝试使用库中的playground并尝试图像及其输出,或者检查repository and docs

答案 4 :(得分:-4)

我喜欢乐观。我喜欢它完全粉碎时所产生的稀疏噪音。

不,JavaScript无法直接进入EXIF;这不是一个安全问题,它只是浏览器无法提供给DOM的东西。

你得到的最接近的是另一个问题所引用的黑客攻击:在服务器端有一个进程来分析图像并通过AJAX&gt;返回EXIF数据。

答案 5 :(得分:-6)

不,对不起。在上传到服务器之前,您无法访问任何文件数据,这肯定是您链接到的库所做的。上传文件后,您可以将其保存在某处,重新下载并从中读取EXIF数据。

上述答案过去是正确的,但现在大多数现代浏览器都允许通过js文件apis进行文件访问。您可以随意使用它,但如果需要跨浏览器支持,您还应该使用服务器端解决方案。