В современных браузерах (все, кроме IE) вы можете использовать конструктор ImageData
, который принимает Uint8ClampedArray в качестве входных данных.
Итак, если ваш работник отправляет Uint8Array , все, что вам нужно сделать - это сначала создать новый Uint8ClampedArray вид того же ArrayBuffer как отправленный TypedArray , а затем используйте это представление для инициализации ImageData :
const worker = new Worker( generateWorkerURL() );
worker.onmessage = (evt) => {
// first a new view (same ArrayBuffer)
const clampedView = new Uint8ClampedArray( evt.data.buffer );
const imageData = new ImageData( clampedView, 500, 300 );
const ctx = document.getElementById( 'canvas' ).getContext( '2d' );
ctx.putImageData( imageData, 0, 0 );
};
// helper to integrate Worker in a Snippet
function generateWorkerURL() {
const content = document.querySelector('[type="worker-script"]').textContent;
const blob = new Blob( [ content ], { type: "text/javascript" } );
return URL.createObjectURL( blob );
}
<script type="worker-script">
// fake worker code, generates noise
const data = Uint8Array.from(
{ length: 500 * 300 * 4 },
() => Math.random() * 0xFF
);
// We 'transfer' the TypedArray's buffer so that it's not copied
// by passing it in an Array as the second argument of postMessage
postMessage( data, [ data.buffer ] );
</script>
<canvas id="canvas" width="500" height="300"></canvas>
Теперь вы даже можете начать работать с ImageData непосредственно в рабочем потоке и перенести его в основной поток, когда это будет сделано:
const worker = new Worker( generateWorkerURL() );
worker.onmessage = (evt) => {
const ctx = document.getElementById( 'canvas' ).getContext( '2d' );
// put directly the imageData sent by the Worker
ctx.putImageData( evt.data, 0, 0 );
};
// helper to integrate Worker in a Snippet
function generateWorkerURL() {
const content = document.querySelector('[type="worker-script"]').textContent;
const blob = new Blob( [ content ], { type: "text/javascript" } );
return URL.createObjectURL( blob );
}
<script type="worker-script">
// fake worker code, generates noise
const imageData = new ImageData( 500, 300 );
for( let i=0; i<imageData.data.length; i++ ) {
imageData.data[ i ] = Math.random() * 0xFF;
}
// we transfer the ImageData's buffer
postMessage( imageData, [ imageData.data.buffer ] );
</script>
<canvas id="canvas" width="500" height="300"></canvas>