【问题标题】:Change image size with ctx.putImageData使用 ctx.putImageData 更改图像大小
【发布时间】:2018-12-25 13:05:52
【问题描述】:

我正在处理 Angular 项目,我必须将图像放在画布上。图片不是本地存储的,我只有图片数据所以我用这个。

this.context.putImageData(imgData, firstPointX, firstPointY);

现在我的问题是我收到的图片是 640 * 480。我想知道是否有办法更改图像尺寸以便我可以显示大于 640 * 480 的尺寸?

【问题讨论】:

    标签: angular html typescript html5-canvas putimagedata


    【解决方案1】:

    putImageData() 将始终使用自己的 widthheight 来表示 destinationWidthdestinationHeight 我们可以在 drawImage()

    对上下文矩阵变换不敏感,因此缩放它不会对这种方法产生影响。

    它有一个东西是 dirtyWidth 和一个 dirtyHeight 参数,这对我们没有多大帮助,虽然它们可以减少将被绘制的表面积,它们不会修改包含的像素,并且无论如何都无法使该表面增长... (您可以查看this Q/A以获得更深入的了解)


    要实现您想要的,您必须实际渲染 ImageData,然后 drawImage 渲染图像。

    最全面的方法可能是使用第二个画布:

    var ctx = canvas.getContext('2d'),
      cW = canvas.width,
      cH = canvas.height,
      imgW = 20,
      imgH = 20;
    
    // generate a 20*20 ImageData full of noise
    var data = new Uint8Array(imgW * imgH * 4);
    crypto.getRandomValues(data);
    var img = new ImageData(new Uint8ClampedArray(data.buffer), imgW, imgH);
    
    
    // generate a second canvas
    var renderer = document.createElement('canvas');
    renderer.width = img.width;
    renderer.height = img.height;
    // render our ImageData on this canvas
    renderer.getContext('2d').putImageData(img, 0, 0);
    // Now we can scale our image, by drawing our second canvas
    ctx.drawImage(renderer, 0,0, cW, cH);
    <canvas id="canvas" height="100" width="100"></canvas>

    在现代浏览器中,由于ImageBitmap 对象,可以以更简洁的方式处理整个事情:

    var ctx = canvas.getContext('2d'),
      cW = canvas.width,
      cH = canvas.height,
      imgW = 20,
      imgH = 20;
    
    // generate a 20*20 ImageData full of noise
    var data = new Uint8Array(imgW * imgH * 4);
    crypto.getRandomValues(data);
    var img = new ImageData(new Uint8ClampedArray(data.buffer), imgW, imgH);
    
    createImageBitmap(img).then(renderer => 
      ctx.drawImage(renderer, 0,0, cW, cH)
    )
    <canvas id="canvas" height="100" width="100"></canvas>

    第三种方法,仅适用于放大 ImageData 并且将避免第二个画布并在所有实现中可用,是使用与 ImageBitmap 渲染器相同的画布,并使用合成将此画布绘制到自身上:

    var ctx = canvas.getContext('2d'),
      cW = canvas.width,
      cH = canvas.height,
      imgW = 20,
      imgH = 20;
    
    // generate a 20*20 ImageData full of noise
    var data = new Uint8Array(imgW * imgH * 4);
    crypto.getRandomValues(data);
    var img = new ImageData(new Uint8ClampedArray(data.buffer), imgW, imgH);
    
    // we use the main canvas as renderer
    ctx.putImageData(img, 0, 0);
    // Now we have an unscaled version of our ImageData
    // let's make the compositing mode to 'copy' so that our next drawing op erases whatever was there previously
    // just like putImageData would have done
    ctx.globalCompositeOperation = 'copy';
    // now we can draw ourself over ourself.
    ctx.drawImage(canvas,
      0,0, img.width, img.height, // grab the ImageData part
      0,0, canvas.width, canvas.height // scale it
    );
    <canvas id="canvas" height="100" width="100"></canvas>

    【讨论】:

      【解决方案2】:

      scale() 方法缩放当前绘图,放大或缩小。

      this.context.putImageData(imgData, firstPointX, firstPointY);
      this.context.scale(1.5,1.5);
      this.context.drawImage(this.canvas, 0, 0); // <-- added
      

      【讨论】:

      • @Chellappan 和丹尼尔,我已经编辑了这个答案,所以现在可以使用了,他只是忘记在缩放后重新绘制画布。
      猜你喜欢
      • 2012-08-04
      • 2010-11-20
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-13
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多