UNPKG

onfido-sdk-ui

Version:

JavaScript SDK view layer for Onfido identity verification

144 lines (122 loc) 3.99 kB
import supportsWebP from 'supports-webp' import loadImage from 'blueimp-load-image' import 'blueimp-load-image/js/load-image-orientation' import 'blueimp-load-image/js/load-image-exif' type Base64ResultCallback = (result: string) => void type CanvasResultCallback = (canvas: HTMLCanvasElement) => void type ErrorCallback = (error: Event) => void type BlobResultCallback = (blob: Blob) => void type FileReaderCallback = (error: ProgressEvent<FileReader>) => void type Base64Blob = { integerArray: Uint8Array mimeString: string } type ImageOptions = { canvas?: boolean maxHeight?: number maxWidth?: number orientation?: boolean } const blobToBase64 = ( blob: Blob, callback: Base64ResultCallback, errorCallback: FileReaderCallback ): void => { const reader = new FileReader() reader.readAsDataURL(blob) reader.onload = () => { callback(reader.result as string) } reader.onerror = function (error) { console.warn('File Reading Error: ', error) errorCallback(error) } } const blobToCanvas = ( blob: Blob, callback: CanvasResultCallback, errorCallback: ErrorCallback, options?: ImageOptions ): void => { const { maxWidth = 960, maxHeight = 960, orientation = true, // `blueimp-load-image` doesn't fallback to use a canvas tag if image // orientation is supported by the browser (see https://caniuse.com/#feat=css-image-orientation). // We rely on a <canvas /> rather than a <img /> for our image operations. // This option forces the library to always use a canvas tag. canvas = true, } = options || {} loadImage( blob, (canvasOrEventError) => { if (canvasOrEventError instanceof Event) { errorCallback(canvasOrEventError) } else if (canvasOrEventError instanceof HTMLCanvasElement) { callback(canvasOrEventError) } else { console.warn('Result mismatched:', canvasOrEventError) } }, { maxWidth, maxHeight, orientation, canvas } ) } const decodeBase64 = (image: string): Base64Blob => { const byteString = atob(image.split(',')[1]) const mimeString = image.split(',')[0].split(':')[1].split(';')[0] const integerArray = new Uint8Array(byteString.length) for (let i = 0; i < byteString.length; i++) { integerArray[i] = byteString.charCodeAt(i) } return { integerArray, mimeString } } const base64toBlob = (image: string): Blob => { const base64Data = decodeBase64(image) return new Blob([base64Data.integerArray], { type: base64Data.mimeString }) } const toDataUrl = (type: string) => ( canvas: HTMLCanvasElement, callback: (dataURL: string) => void ) => callback(canvas.toDataURL(type)) export const canvasToBlob = ( canvas: HTMLCanvasElement, callback: BlobResultCallback, mimeType = 'image/png' ): void => { if (!HTMLCanvasElement.prototype.toBlob) { // Handle browsers that do not support canvas.toBlob() like Edge const dataUrlImg = canvas.toDataURL() callback(base64toBlob(dataUrlImg)) return } canvas.toBlob((blob) => blob && callback(blob), mimeType) } export const blobToLossyBase64 = ( blob: Blob, callback: Base64ResultCallback, errorCallback: FileReaderCallback, options?: ImageOptions ): void => { const browserSupportedLossyFormat = `image/${supportsWebP ? 'webp' : 'jpeg'}` const toLossyImageDataUrl = toDataUrl(browserSupportedLossyFormat) const asBase64 = () => blobToBase64(blob, callback, errorCallback) const asLossyBase64 = () => blobToCanvas( blob, (canvas) => toLossyImageDataUrl(canvas, callback), asBase64, options ) isOfMimeType(['pdf'], blob) ? asBase64() : asLossyBase64() } export const mimeType = (blob?: Blob): Optional<string> => { if (!blob || !blob.type) { return null } return blob.type.split('/')[1] } export const isOfMimeType = (mimeTypeList: string[], blob: Blob): boolean => mimeTypeList.some( (acceptableMimeType) => acceptableMimeType === mimeType(blob) )