JavaScript: могу ли я прочитать данные EXIF из файла загрузки?
У меня есть следующая задача:
- Предложить
<input type=file />
- Когда пользователь добавляет файл:
- читать данные EXIF (в частности, информацию о местоположении, если она доступна)
- отправить файл и информацию из EXIF во внешний API, используя Ajax
Итак, я хотел бы использовать JavaScript для извлечения некоторых данных EXIF при добавлении файла в input
,
Это возможно?
Я знаю об этом вопросе: Могу ли я прочитать данные Exif изображения на стороне клиента с помощью js?, который ссылается на http://blog.nihilogic.dk/2008/05/reading-exif-data-with-javascript.html
Но мой вопрос (я думаю?) Немного другой - я хочу извлечь данные EXIF, прежде чем изображение окажется даже в моем домене, в то время как оно находится в локальной файловой системе пользователя, если вы понимаете, о чем я. Я могу получить доступ к двоичным данным, поэтому я тоже могу получить EXIF?
Спасибо за совет.
8 ответов
Нет извините. Вы не можете получить доступ к каким-либо данным файла, пока они не будут загружены на сервер, что, безусловно, делает библиотека, с которой вы связаны. Как только файл загружен, вы можете сохранить его где-нибудь, повторно загрузить и прочитать данные EXIF из него.
Приведенный выше ответ был правильным, но большинство современных браузеров теперь разрешают доступ к файлу через файл js apis. Не стесняйтесь использовать это, но вы должны также использовать решение на стороне сервера, если требуется кросс-браузерная поддержка.
Вы можете сделать это на клиенте с HTML5. У вас должен быть подходящий серверный запасной вариант для старых браузеров, которые не поддерживают File и FileReader.
Вы можете написать свой собственный анализатор exif или использовать библиотеку jsjpegmeta(Бен Лесли), которая представляет собой простую + потрясающую библиотеку, которая позволяет браузеру извлекать данные EXIF из большинства файлов jpeg. Существует патч, в котором говорится, что он устраняет большинство проблем с совместимостью. Я не тестировал патч, но будьте готовы раскошелиться на проект и надеть шапку Github.
Чтобы получить EXIF:
- Диалог открытия файла: я обычно создаю кнопку, которая вызывает функцию для генерации
<file
введите и добавьте обработчик изменений - Получить файлы: В обработчике изменения файла UE
$(this).get(0).files
чтобы получить список выбранных файлов. - Анализ данных exif: отправьте результаты просмотра в jsjpegmeta
Мне пришлось немного настроить библиотеку, чтобы она делала то, что я хотел (я хотел общую библиотеку JS), я также сделал настройку, указанную в выпуске 1.
Я знаю, что это, возможно, уже решено, но я хотел бы предложить альтернативное решение для людей, которые сталкиваются с этим вопросом.
Есть новая библиотека 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)
})
Вы также можете опробовать игровую площадку библиотеки и поэкспериментировать с изображениями и их выводом или заглянуть в репозиторий и документацию.
Я только что нашел exif-js из npm.
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}
/>
Результат должен быть таким.
Ответ Шанималя верен, но он не перестает удивлять меня тем, как люди усложняются. Вот реализация библиотеки 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>
Пришёл сюда в 2023 году, потому что искал похожее решение. Библиотеки, упомянутые во всех ответах, кажутся довольно устаревшими. Однако на npm есть поддерживаемая библиотека: https://www.npmjs.com/package/exifreader .
Для чтения exif на стороне клиента мы можем использовать его следующим образом:
включить lib в html
<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
})
Да, с помощью современного браузера вы можете читать содержимое файлов и извлекать exif. ссылка, которую вы показываете, является примером. проблема в том, что на старых браузерах IE6-9, FF 3.6- это невозможно. Также вы должны учитывать, что браузеру сложно читать и извлекать exif из больших файлов.
Я люблю оптимизм. Мне нравится этот шум сплайтов, который он издает, когда он полностью раздавлен.
Нет, JavaScript не может напрямую попасть в EXIF; это не проблема безопасности, это просто то, что не доступно браузеру для DOM.
Самое близкое, что вы получите, - это именно тот хак, на который ссылался другой вопрос: создать на стороне сервера процесс для анализа изображения и возврата данных EXIF через AJAX>.