Strip EXIF data before upload on client (#634)
Co-authored-by: ekzyis <ek@stacker.news>
This commit is contained in:
parent
a318727f9c
commit
158baa61e3
|
@ -150,8 +150,9 @@ export const ImageUpload = forwardRef(({ children, className, onSelect, onUpload
|
|||
}
|
||||
}`)
|
||||
|
||||
const s3Upload = useCallback(file => {
|
||||
const s3Upload = useCallback(async file => {
|
||||
const img = new window.Image()
|
||||
file = await removeExifData(file)
|
||||
img.src = window.URL.createObjectURL(file)
|
||||
return new Promise((resolve, reject) => {
|
||||
img.onload = async () => {
|
||||
|
@ -232,3 +233,42 @@ export const ImageUpload = forwardRef(({ children, className, onSelect, onUpload
|
|||
</>
|
||||
)
|
||||
})
|
||||
|
||||
// from https://stackoverflow.com/a/77472484
|
||||
const removeExifData = (file) => {
|
||||
const cleanBuffer = (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
|
||||
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, offset, length) => {
|
||||
// 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
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
if (!file || !file.type.startsWith('image/')) return resolve(file)
|
||||
const fr = new window.FileReader()
|
||||
fr.onload = function () {
|
||||
const cleanedBuffer = cleanBuffer(this.result)
|
||||
const blob = new Blob([cleanedBuffer], { type: file.type })
|
||||
const newFile = new File([blob], file.name, { type: file.type })
|
||||
resolve(newFile)
|
||||
}
|
||||
fr.readAsArrayBuffer(file)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue