sanity
Version:
Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches
38 lines (33 loc) • 1.27 kB
text/typescript
import exif from 'exif-component'
import {from as observableFrom, Observable, of as observableOf} from 'rxjs'
import {catchError, map} from 'rxjs/operators'
function readFileAsArrayBuffer(
file: File,
length: number,
): Observable<string | ArrayBuffer | null> {
return new Observable((observer) => {
const reader = new window.FileReader()
reader.onerror = (err) => observer.error(err)
reader.onload = () => {
observer.next(reader.result)
observer.complete()
}
reader.readAsArrayBuffer(length === undefined ? file : file.slice(0, length))
return () => reader.abort()
})
}
const SKIP_EXIF_ERROR_RE = /(invalid image format)|(No exif data)/i
// 128k should be enough for exif data according to https://github.com/mattiasw/ExifReader#tips
const EXIF_BUFFER_LENGTH = 128000
export function readExif(file: File) {
return observableFrom(readFileAsArrayBuffer(file, EXIF_BUFFER_LENGTH)).pipe(
map((buf) => exif(buf)),
catchError((error) => {
if (!SKIP_EXIF_ERROR_RE.test(error.message)) {
// Exif read failed, we do not want to fail hard
console.warn(`Exif read failed, continuing anyway: ${error.message}`) // eslint-disable-line no-console
}
return observableOf({})
}),
)
}