在客户端访问 JavaScript 中的 JPEG EXIF 旋转数据
2022-08-30 04:15:41
我想根据照片的原始旋转来旋转照片,这是相机在JPEG EXIF图像数据中设置的。诀窍是,所有这些都应该在浏览器中发生,使用JavaScript和。<canvas>
JavaScript如何访问JPEG,本地文件API对象,本地或远程,EXIF数据来读取旋转信息?<img>
<img>
服务器端答案不行;我正在寻找客户端解决方案。
我想根据照片的原始旋转来旋转照片,这是相机在JPEG EXIF图像数据中设置的。诀窍是,所有这些都应该在浏览器中发生,使用JavaScript和。<canvas>
JavaScript如何访问JPEG,本地文件API对象,本地或远程,EXIF数据来读取旋转信息?<img>
<img>
服务器端答案不行;我正在寻找客户端解决方案。
如果你只想要方向标签,而不需要其他任何东西,并且不喜欢包含另一个巨大的javascript库,我写了一些代码来尽可能快地提取方向标签(它使用DataView,在IE10 +中可用,但你可以为较旧的浏览器编写自己的数据读取器):readAsArrayBuffer
function getOrientation(file, callback) {
var reader = new FileReader();
reader.onload = function(e) {
var view = new DataView(e.target.result);
if (view.getUint16(0, false) != 0xFFD8)
{
return callback(-2);
}
var length = view.byteLength, offset = 2;
while (offset < length)
{
if (view.getUint16(offset+2, false) <= 8) return callback(-1);
var marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1)
{
if (view.getUint32(offset += 2, false) != 0x45786966)
{
return callback(-1);
}
var little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
var tags = view.getUint16(offset, little);
offset += 2;
for (var i = 0; i < tags; i++)
{
if (view.getUint16(offset + (i * 12), little) == 0x0112)
{
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
}
}
else if ((marker & 0xFF00) != 0xFF00)
{
break;
}
else
{
offset += view.getUint16(offset, false);
}
}
return callback(-1);
};
reader.readAsArrayBuffer(file);
}
// usage:
var input = document.getElementById('input');
input.onchange = function(e) {
getOrientation(input.files[0], function(orientation) {
alert('orientation: ' + orientation);
});
}
<input id='input' type='file' />
值:
-2: not jpeg
-1: not defined
对于使用 Typescript 的用户,您可以使用以下代码:
export const getOrientation = (file: File, callback: Function) => {
var reader = new FileReader();
reader.onload = (event: ProgressEvent) => {
if (! event.target) {
return;
}
const file = event.target as FileReader;
const view = new DataView(file.result as ArrayBuffer);
if (view.getUint16(0, false) != 0xFFD8) {
return callback(-2);
}
const length = view.byteLength
let offset = 2;
while (offset < length)
{
if (view.getUint16(offset+2, false) <= 8) return callback(-1);
let marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1) {
if (view.getUint32(offset += 2, false) != 0x45786966) {
return callback(-1);
}
let little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
let tags = view.getUint16(offset, little);
offset += 2;
for (let i = 0; i < tags; i++) {
if (view.getUint16(offset + (i * 12), little) == 0x0112) {
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
}
} else if ((marker & 0xFF00) != 0xFF00) {
break;
}
else {
offset += view.getUint16(offset, false);
}
}
return callback(-1);
};
reader.readAsArrayBuffer(file);
}
您可以将exif-js库与HTML5 File API结合使用:http://jsfiddle.net/xQnMd/1/。
$("input").change(function() {
var file = this.files[0]; // file
fr = new FileReader; // to read file contents
fr.onloadend = function() {
// get EXIF data
var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
// alert a value
alert(exif.Make);
};
fr.readAsBinaryString(file); // read the file
});