import BackgroundFilterSpec from '../backgroundfilter/BackgroundFilterSpec' ; import BackgroundBlurOptions from './BackgroundBlurOptions' ; import BackgroundBlurProcessorProvided from './BackgroundBlurProcessorProvided' ; import { BlurStrengthMapper } from './BackgroundBlurStrength' ; /**
 * The [[BackgroundBlurProcessorBuiltIn]] uses the browser's built-in capability to apply blurring to
 * the background image as apposed to [[BackgroundBlurProcessorProvided]] that uses WASM and
 * TensorFlow Lite to apply the blur.
 */ internal export default class BackgroundBlurProcessorBuiltIn extends BackgroundBlurProcessorProvided { private blurredImage : ImageData ; private blurCanvas : HTMLCanvasElement = document . createElement ( 'canvas' ) as HTMLCanvasElement ; private blurCanvasCtx = this . blurCanvas . getContext ( '2d' ) ; param spec param options constructor ( spec ? , options ? ) { super ( spec , options ) ; this . blurCanvas . width = this . spec . model . input . width ; this . blurCanvas . height = this . spec . model . input . height ; this . logger . info ( 'BackgroundBlur processor using builtin blur' ) ; } drawImageWithMask ( inputCanvas , mask ) { const blurredImage = this . blurredImage ; const { canvasCtx , targetCanvas } = this ; const { width , height } = targetCanvas ; if ( ! mask || ! blurredImage ) { canvasCtx . clearRect ( 0 , 0 , width , height ) ; return ; } const scaledCtx = this . scaledCanvas . getContext ( '2d' ) ; scaledCtx . putImageData ( mask , 0 , 0 ) ; this . blurCanvasCtx . putImageData ( this . blurredImage , 0 , 0 ) ; canvasCtx . save ( ) ; canvasCtx . clearRect ( 0 , 0 , width , height ) ; canvasCtx . drawImage ( this . scaledCanvas , 0 , 0 , width , height ) ; canvasCtx . globalCompositeOperation = 'source-in' ; canvasCtx . drawImage ( inputCanvas , 0 , 0 , width , height ) ; canvasCtx . globalCompositeOperation = 'destination-over' ; canvasCtx . drawImage ( this . blurCanvas , 0 , 0 , width , height ) ; canvasCtx . restore ( ) ; } setBlurStrength ( blurStrength ) { super . setBlurStrength ( blurStrength ) ; if ( this . worker ) { this . modelInitialized = false ; this . worker . postMessage ( { msg : 'destroy' } ) ; const model = this . spec . model ; this . worker . postMessage ( { msg : 'loadModel' , payload : { modelUrl : model . path , inputHeight : model . input . height , inputWidth : model . input . width , inputChannels : 4 , modelRangeMin : model . input . range [ 0 ] , modelRangeMax : model . input . range [ 1 ] , blurPixels : this . blurAmount , } , } ) ; } } setBlurPixels ( ) { this . blurAmount = BlurStrengthMapper . getBlurAmount ( this . _blurStrength , { height : 540 } ) ; this . logger . info ( `background blur amount set to ${ this . blurAmount }` ) ; } handleInitialize ( msg ) { this . logger . info ( `received initialize message: ${ this . stringify ( msg ) }` ) ; if ( ! msg . payload ) { this . logger . error ( 'failed to initialize module' ) ; this . initWorkerPromise . reject ( new Error ( 'failed to initialize the module' ) ) ; return ; } const model = this . spec . model ; this . worker . postMessage ( { msg : 'loadModel' , payload : { modelUrl : model . path , inputHeight : model . input . height , inputWidth : model . input . width , inputChannels : 4 , modelRangeMin : model . input . range [ 0 ] , modelRangeMax : model . input . range [ 1 ] , blurPixels : this . blurAmount , } , } ) ; this . initWorkerPromise . resolve ( { } ) ; } handlePredict ( msg ) { this . blurredImage = msg . payload . blurOutput ; super . handlePredict ( msg ) ; } async destroy ( ) { super . destroy ( ) ; this . blurCanvas ?. remove ( ) ; this . blurCanvas = undefined ; } }