JavaScript:我可以从文件上传输入中读取 EXIF 数据吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5784459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript: can I read EXIF data from a file upload input?
提问by simon
I have the following task:
我有以下任务:
- Offer an
<input type=file />
- When the user adds a file:
- read the EXIF data (specifically, location information if available)
- send the file and the information from the EXIF to an external API, using Ajax
- 提供一个
<input type=file />
- 当用户添加文件时:
- 读取 EXIF 数据(特别是位置信息,如果可用)
- 使用 Ajax 将文件和信息从 EXIF 发送到外部 API
So, I'd like to use JavaScript to extract some EXIF data when a file is added to the input
.
所以,当文件被添加到input
.
Is this possible?
这可能吗?
I know about this question: Can I read Exif data of a picture in the client-side with js?, which refers to http://blog.nihilogic.dk/2008/05/reading-exif-data-with-javascript.html
我知道这个问题:我可以用js读取客户端图片的Exif数据吗?, 指的是http://blog.nihilogic.dk/2008/05/reading-exif-data-with-javascript.html
But my question is (I think?) slightly different - I want to extract the EXIF data before the image is even on my domain, while it's on the user's local filesystem, if you see what I mean. I can access the binary data, so can I get the EXIF too?
但我的问题是(我认为?)略有不同 - 我想在图像甚至在我的域中之前提取 EXIF 数据,而它在用户的本地文件系统上,如果你明白我的意思。我可以访问二进制数据,那么我也可以获得 EXIF 吗?
Thanks for your advice.
谢谢你的建议。
采纳答案by Mark Kahn
No, sorry. You can't access any of the file data until it's uploaded to the server, which is certainly what the library you linked to does. Once the file is uploaded, you can save it somewhere, re-download it and read EXIF data from it.
不,对不起。在将文件数据上传到服务器之前,您无法访问任何文件数据,这当然是您链接到的库所做的。文件上传后,您可以将其保存在某处,重新下载并从中读取 EXIF 数据。
The above answer used to be correct, but most modern browsers now allow file access via the js file apis. Feel free to use that, but you should also use a server-side solution if cross-browser support is required.
上面的答案曾经是正确的,但大多数现代浏览器现在允许通过 js 文件 apis 访问文件。随意使用它,但如果需要跨浏览器支持,您也应该使用服务器端解决方案。
回答by Shanimal
You can do this on the client with HTML5. You should have an appropriate server based fallback for older browsers that don't support File and FileReader.
您可以使用 HTML5 在客户端上执行此操作。对于不支持 File 和 FileReader 的旧浏览器,您应该有一个适当的基于服务器的回退。
You can write your own exif parser or use the jsjpegmeta library(Ben Leslie), which is a simple+awesome library that lets the browser extract the EXIF data from most jpeg files. There is a patchthat says it fixes most of the compatibility problems. I haven't tested the patch, but be prepared to fork the project and put on your github hat.
您可以编写自己的 exif 解析器或使用jsjpegmeta 库(Ben Leslie),这是一个简单且很棒的库,可让浏览器从大多数 jpeg 文件中提取 EXIF 数据。有一个补丁说它修复了大部分兼容性问题。我还没有测试补丁,但准备好 fork 项目并戴上你的 github 帽子。
To get the EXIF:
要获取 EXIF:
- Open file dialog:I usually create a button that calls a function to generate the
<file
input and add a change handler - Get the files:In the file change handler ue
$(this).get(0).files
to get the list of selected files. - Parse the exif data:Send the browse results to jsjpegmeta
- 打开文件对话框:我通常创建一个按钮,调用函数来生成
<file
输入并添加更改处理程序 - 获取文件:在文件更改处理程序 ue
$(this).get(0).files
中获取所选文件的列表。 - 解析exif数据:将浏览结果发送到jsjpegmeta
I had to tweak the library a bit to get it to do what I wanted (I wanted a commonJS library) I also made the tweak identified in issue 1.
我必须稍微调整一下库才能让它做我想做的事(我想要一个 commonJS 库)我也做了在问题 1 中确定的调整。
回答by mgrahamjo
Shanimal's answer is correct, but it never ceases to amaze me how overcomplicated people make things. Here is an implementation of the jsjpegmetalibrary that accomplishes the same thing, if you don't need to support multiple file uploads:
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>
回答by Mike Kova?ík
I know this may be already solved but I'd like to offer an alternative solution, for the people stumbling upon this question.
我知道这可能已经解决了,但我想为那些在这个问题上绊倒的人提供一个替代解决方案。
There's a new library exifrwith which you can do exactly that. It's maintained, actively developed library with focus on performance and works in both nodejs and browser.
有一个新的库exifr,您可以使用它来做到这一点。它是维护的、积极开发的库,专注于性能,可在 nodejs 和浏览器中使用。
Simple example of extracting exif from one file:
从一个文件中提取 exif 的简单示例:
document.querySelector('#filepicker').addEventListener('change', async e => {
let file = e.target.files[0]
let exifData = await exif.parse(file)
console.log('exifData', exifData)
})
Complex example of extracting exif from multile files:
从多个文件中提取 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)
})
And you can even extract thumbnail thats embedded in the file:
您甚至可以提取嵌入在文件中的缩略图:
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)
})
You can also try out the library's playgroundand experiment with images and their output, or check out the repository and docs.
回答by albanx
Yes with modern browser you can read files contents and so extract exif. the link you show is an example. the problem is that on old browsers IE6-9, FF 3.6- this is not possible. Also you should consider the it is a hard process for browser to read and extract exif from big files.
是的,使用现代浏览器,您可以读取文件内容并提取 exif。您显示的链接是一个示例。问题是在旧浏览器 IE6-9、FF 3.6 上这是不可能的。您还应该考虑到浏览器从大文件中读取和提取 exif 是一个艰难的过程。
回答by Malvolio
I love optimism. I love that sploity noise it makes when it's utterly crushed.
我爱乐观。我喜欢它被完全压碎时发出的那种混乱的声音。
No, JavaScript cannot get to EXIF directly; this is not a security issue, it's just something that isn't made available by the browser to the DOM.
不,JavaScript 不能直接访问 EXIF;这不是安全问题,它只是浏览器无法提供给 DOM 的东西。
The closest you get get is exactly the hack that the other question referred to: have a process on the server side to analyze the image and return the EXIF data via AJAX>.
您得到的最接近的正是另一个问题所提到的 hack:在服务器端有一个进程来分析图像并通过 AJAX> 返回 EXIF 数据。