我如何通过JavaScript从上传的图像中删除EXIF数据?我目前可以使用这个exif-js插件访问EXIF数据,就像这样:
EXIF.getData(oimg, function() {
var orientation = EXIF.getTag(this, "Orientation");
});
然而,我并没有找到任何实际删除Exif数据的方法,只能检索它。
更具体地说,我正在尝试这样做是为了摆脱方向Exif数据,在某些浏览器上旋转我的图像。
我如何通过JavaScript从上传的图像中删除EXIF数据?我目前可以使用这个exif-js插件访问EXIF数据,就像这样:
EXIF.getData(oimg, function() {
var orientation = EXIF.getTag(this, "Orientation");
});
然而,我并没有找到任何实际删除Exif数据的方法,只能检索它。
更具体地说,我正在尝试这样做是为了摆脱方向Exif数据,在某些浏览器上旋转我的图像。
这是一个小演示,选择带有方向数据的图像,查看它在有或没有该数据的情况下的展示效果(仅限现代浏览器)。
http://jsfiddle.net/mowglisanu/frhwm2xe/3/
var input = document.querySelector('#erd');
input.addEventListener('change', load);
function load(){
var fr = new FileReader();
fr.onload = process;
fr.readAsArrayBuffer(this.files[0]);
document.querySelector('#orig').src = URL.createObjectURL(this.files[0]);
}
function process(){
var dv = new DataView(this.result);
var offset = 0, recess = 0;
var pieces = [];
var i = 0;
if (dv.getUint16(offset) == 0xffd8){
offset += 2;
var app1 = dv.getUint16(offset);
offset += 2;
while (offset < dv.byteLength){
//console.log(offset, '0x'+app1.toString(16), recess);
if (app1 == 0xffe1){
pieces[i] = {recess:recess,offset:offset-2};
recess = offset + dv.getUint16(offset);
i++;
}
else if (app1 == 0xffda){
break;
}
offset += dv.getUint16(offset);
var app1 = dv.getUint16(offset);
offset += 2;
}
if (pieces.length > 0){
var newPieces = [];
pieces.forEach(function(v){
newPieces.push(this.result.slice(v.recess, v.offset));
}, this);
newPieces.push(this.result.slice(recess));
var br = new Blob(newPieces, {type: 'image/jpeg'});
document.querySelector('#mod').src = URL.createObjectURL(br);
}
}
}
img{
max-width:200px;
}
<input id="erd" type="file"/><br>
<img id="orig" title="Original">
<img id="mod" title="Modified">
dataview.setUint16(orientationOffset, newValue)
这样。 - MusaEXIF数据仅存在于TIFF、JPEG(JPG)和HEIC格式的图像中,而不包含在png和gif图像中。
首先,让我们了解图像包含的内容。
图像缓冲区包含一个头部(2个字节)+数据。
数据部分包含许多段,每个段都包含一个头部(2个字节)+数据。
段的长度在数据的第一个字节中表示(或在段开始后的2个字节之后)。
Exif缓冲段以'0xFFE1'开头
[头部=标记]
下面的代码是TS(只需删除类型,它将在js中工作)
const cleanBuffer = (arrayBuffer: ArrayBuffer) => {
let dataView = new DataView(arrayBuffer);
const exifMarker = 0xffe1;
let offset = 2; // Skip the first two bytes (0xFFD8)
while (offset < dataView.byteLength) {
if (dataView.getUint16(offset) === exifMarker) {
// Found an EXIF marker
const segmentLength = dataView.getUint16(offset + 2, false) + 2;
// Update the arrayBuffer and dataView
arrayBuffer = removeSegment(arrayBuffer, offset, segmentLength);
dataView = new DataView(arrayBuffer)
} else {
// Move to the next marker
offset += 2 + dataView.getUint16(offset + 2, false);
}
}
return arrayBuffer;
};
const removeSegment = (buffer: ArrayBuffer, offset: number, length: number) => {
// Create a new buffer without the specified segment
const modifiedBuffer = new Uint8Array(buffer.byteLength - length);
modifiedBuffer.set(new Uint8Array(buffer.slice(0, offset)), 0);
modifiedBuffer.set(new Uint8Array(buffer.slice(offset + length)), offset);
return modifiedBuffer.buffer;
};
const removeExifData = (file: File): Promise<File> => {
return new Promise((resolve) => {
if (file && file.type.startsWith('image/')) {
const fr = new FileReader();
fr.onload = function (this: FileReader) {
const cleanedBuffer = cleanBuffer(this.result as ArrayBuffer);
const blob = new Blob([cleanedBuffer], { type: file.type });
const newFile = new File([blob], file.name, { type: file.type });
resolve(newFile);
};
fr.readAsArrayBuffer(file);
} else resolve(file);
});
};