【问题标题】:How to rotate an image in a canvas?如何旋转画布中的图像?
【发布时间】:2020-07-11 10:53:44
【问题描述】:

我正在尝试使用 d3 从 json 文件中绘制图像。然后将此图像数据放入画布上下文中以实际绘制图像。我想旋转生成的图像,但找不到方法。我实际使用的代码

$(document).ready(function() {
    d3.json("resources/image.json").then(function(image) {
        var canvas = d3.select("colorImage")
                       .append("canvas")
                       .attr("width", 200)
                       .attr("height", 200);


        var context = canvas.node().getContext("2d");
        var image_data = context.createImageData(200, 200);

        image_data.data.set(image);
        context.rotate(60); 
        context.putImageData(image_data, 0, 0);  // <---- image not rotated
        context.fillRect( 100, 100, 20, 20 );  // <--- rectangle rotated
    }).catch(function(error){
        if (error) throw error;
    });
})

【问题讨论】:

  • 你试过这个堆栈溢出答案吗:stackoverflow.com/a/29398757/7548672
  • 是的,但这似乎是我构建图像的方式的问题。我还尝试将其嵌入到“内存中”画布中,但没有成功。
  • 你能把你的 json 添加到一个变量中并创建一个功能齐全的 sn-p 吗?

标签: javascript d3.js canvas html5-canvas


【解决方案1】:

putImageData()getImageData() 不受上下文转换矩阵的影响。

要旋转它,最简单的方法是从它 create an ImageBitmap 并使用 drawImage() 绘制该 ImageBitmap:

(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 );
&lt;canvas id="canvas" height="300" width="300"&gt;&lt;/canvas&gt;

对于不支持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 );
    }
  };
}
&lt;canvas id="canvas" height="300" width="300"&gt;&lt;/canvas&gt;

【讨论】:

    猜你喜欢
    • 2016-01-12
    • 2015-10-01
    • 2016-03-13
    • 2017-09-26
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多