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

问题描述 投票:0回答:7

我有以下任务:

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

因此,我想在将文件添加到

input
时使用JavaScript来提取一些EXIF数据。

这可能吗?

我知道这个问题:我可以在客户端用js读取图片的Exif数据吗?,参考http://blog.nihilogic.dk/2008/05/reading-exif-data- with-javascript.html

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

感谢您的建议。

javascript jquery image exif
7个回答
7
投票

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

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

获取 EXIF:

    打开文件对话框:
  1. 我通常创建一个按钮,调用函数来生成<file输入并添加更改处理程序
  2. 获取文件:
  3. 在文件更改处理程序 ue $(this).get(0).files 中获取所选文件的列表。
  4. 解析exif数据:
  5. 将浏览结果发送到jsjpegmeta
  6. 我必须对库进行一些调整才能让它执行我想要的操作(我想要一个 commonJS 库),我还进行了问题 1 中确定的调整。

这是一把小提琴

更新2022年7月26日

该软件包已移至 Gitlab。该补丁已包含在最新版本中。您可以在这里找到该包。


2
投票

有一个新的库

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

并尝试图像及其输出,或者查看 存储库和文档


1
投票

https://github.com/exif-js/exif-js

我是在反应中这样做的。 这是我的代码。 它对我来说非常有效

import EXIF from 'exif-js'; //...... const fileChangedHandler = (event) => { const files = event.target.files; console.log(files[0]); EXIF.getData(files[0], function () { console.log(EXIF.getAllTags(this)); }); }; //...... <input type="file" onChange={fileChangedHandler} />

结果应该是这样的。


0
投票


0
投票
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>



0
投票
https://www.npmjs.com/package/exifreader

为了在客户端读取 exif,我们可以这样使用它:

在 html 中包含 lib

<script src="/path/to/exif-reader.js"></script>

读取图像文件并提取exif

// example code adapted from exifreader docs document.querySelector('input[type="file"]').addEventListener('change', async e => { const file = e.target.files[0]; const tags = await ExifReader.load(file); // example exif tag access const imageDate = tags['DateTimeOriginal'].description; const unprocessedTagValue = tags['DateTimeOriginal'].value; // ...more processing here })



-5
投票

您得到的最接近的正是另一个问题提到的 hack:在服务器端有一个进程来分析图像并通过 AJAX 返回 EXIF 数据>。

© www.soinside.com 2019 - 2024. All rights reserved.