import { blobToBase64, base64ToDataURL, checkResponse } from './Common.js'
/**
* ImageSource
* @classdesc Class to handle loading various image formats
*
* @see {@link Probe}
*/
export class ImageSource {
source
url
imageData
type
/**
* Instantiate an ImageSource
* @constructor
* @param {string} source - The source of the image data.
* @param {string} [type] - The type of data in the image source, valid values
* are 'url', 'base64', and 'dataurl'. If not provided 'base64' is the default.
*
* @example
* const personPhoto = new ImageSource('/person/123.jpg', 'url')
*/
constructor (source, type = 'base64') {
// TODO:
// If the source is typeof object and/or type=object we should do some duck
// typing and accept any of...
// - The result of an ICAO check that contains a cropped image
// - An Image tag (fetch the source)
// - A Blob
// - An Array Buffer
// - An object that has a fullCapture method (call function in .data())
this.type = type
switch (this.type) {
case 'url':
this.url = source
break
case 'base64':
this.imageData = source
break
case 'dataurl':
this.imageData = source.split(',')[1]
break
case undefined:
case null:
default:
throw new Error('Invalid image source type provided')
}
}
/**
* Fetch the image data and base64 encode it
* @async
* @example
* const personPhoto = new ImageSource("/img/photo.jpg")
* await personPhoto.data()
* console.log(personPhoto.imageData)
*/
async data () {
if (!this.imageData && this.url) {
const response = await fetch(this.url)
await checkResponse(response)
const blob = await response.blob()
this.imageData = await blobToBase64(blob)
}
return this.imageData
}
/**
* Create an <img> element, wait for it to load and return it
* @async
* @example
* // Load the image and draw it on a Canvas
* const img = await imgSrc.toImage()
* const canvas = document.createElement('canvas')
* const ctx = canvas.getContext('2d')
* canvas.width = img.width
* canvas.height = img.height
* ctx.drawImage(img, canvas.width, canvas.height, img.width, img.height)
*/
async toImage () {
const img = new window.Image()
const promise = new Promise((resolve, reject) => {
img.onload = (data) => resolve(img)
img.onerror = (err) => reject(err)
})
switch (this.type) {
case 'url':
img.src = this.url
break
case 'base64':
case 'dataurl':
img.src = base64ToDataURL(this.imageData)
break
case undefined:
case null:
default:
throw new Error('Invalid image source type provided')
}
return promise
}
toJSON () {
return this.imageData
}
}
export default ImageSource