putImageData()
и getImageData()
не зависят от матрицы преобразования контекста.
Чтобы повернуть ее, проще всего создать ImageBitmap из него и для рисования этого ImageBitmap используйте drawImage()
:
(async () => {
const canvas = document.getElementById( 'canvas' );
const context = canvas.getContext( '2d' );
// make some noise
const image = new Uint8Array( Uint32Array.from(
{ length: 200 * 200 },
_ => (Math.random() * 0xFFFFFFFF)
).buffer );
const image_data = context.createImageData( 200, 200 );
image_data.data.set( image );
const center_w = canvas.width / 2;
const center_h = canvas.height / 2;
const bitmap = await createImageBitmap( image_data );
context.translate( center_w, center_h );
context.rotate( 60 );
context.translate( -center_w, -center_h );
context.drawImage( bitmap, center_w-100, center_h-100 ); // <---- image rotated
context.lineWidth = 4;
context.strokeStyle = 'green';
context.strokeRect( center_w-100, center_h-100, 200, 200 ); // <--- rectangle rotated
})().catch( console.error );
<canvas id="canvas" height="300" width="300"></canvas>
А для браузеров, которые не поддерживают метод createImageBitmap()
, вы можете довольно легко исправить это точное использование с помощью HTMLCanvasElement:
/* if( !window.createImageBitmap ) { */ // for demo we force monkey-patch
monkeyPatchCreateImageBitmap();
/*} */
(async () => {
const canvas = document.getElementById( 'canvas' );
const context = canvas.getContext( '2d' );
// make some noise
const image = new Uint8Array( Uint32Array.from(
{ length: 200 * 200 },
_ => (Math.random() * 0xFFFFFFFF)
).buffer );
const image_data = context.createImageData( 200, 200 );
image_data.data.set( image );
const center_w = canvas.width / 2;
const center_h = canvas.height / 2;
const bitmap = await createImageBitmap( image_data );
context.translate( center_w, center_h );
context.rotate( 60 );
context.translate( -center_w, -center_h );
context.drawImage( bitmap, center_w-100, center_h-100 ); // <---- image rotated
context.lineWidth = 4;
context.strokeStyle = 'green';
context.strokeRect( center_w-100, center_h-100, 200, 200 ); // <--- rectangle rotated
})().catch( console.error );
// minimalistic version that only accepts ImageData, and no clipping
function monkeyPatchCreateImageBitmap() {
window.createImageBitmap = function( source ) {
if( source instanceof ImageData ) {
const dest = document.createElement( 'canvas' );
dest.width = source.width;
dest.height = source.height;
dest.getContext( '2d' ).putImageData( source, 0, 0 );
return Promise.resolve( dest );
}
};
}
<canvas id="canvas" height="300" width="300"></canvas>