从图像中去除 EXIF 数据

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

如何通过javascript从上传的图片中去除EXIF数据?我目前可以使用这个 exif-js 插件访问 EXIF 数据,如下所示:

EXIF.getData(oimg, function() {
    var orientation = EXIF.getTag(this, "Orientation");
});

但是,我还没有找到任何方法来实际删除 Exif 数据,只能检索它。

更具体地说,我试图这样做是为了摆脱在某些浏览器上旋转我的图像的方向 Exif 数据。

javascript exif
2个回答
27
投票

这是它的一个小演示,选择带有方向数据的图像来查看使用和不使用它时的外观(仅限现代浏览器)。

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">


0
投票
Exif 数据仅存在于 TIFF、JPEG(JPG) 和 HEIC 中,但不存在于 png、gif 图像中

图像缓冲区包含标头(2字节)+数据。

数据部分包含很多段,每个段包含一个 header(2bytes) + data。

段的长度出现在数据的第一个字节中(或从段开始起的 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); }); };

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