如何在HTML画布中缩放imageData?

Mas*_*iar 31 html canvas getimagedata

我的网页上有画布; 我在这个画布中创建了一个新的Image数据,然后我通过myImgData.data []数组修改了一些像素.现在我想缩放此图像并使其更大.我尝试通过缩放上下文但图像仍然很小.是否有可能做到这一点?谢谢

Cas*_*nge 36

您可以将imageData绘制到新画布,缩放原始画布,然后将新画布绘制到原始画布.

这样的事情应该有效:

var imageData = context.getImageData(0, 0, 100, 100);
var newCanvas = $("<canvas>")
    .attr("width", imageData.width)
    .attr("height", imageData.height)[0];

newCanvas.getContext("2d").putImageData(imageData, 0, 0);

context.scale(1.5, 1.5);
context.drawImage(newCanvas, 0, 0);
Run Code Online (Sandbox Code Playgroud)

这是一个功能正常的演示http://jsfiddle.net/Hm2xq/2/.

  • 我想补充一点,你可以在不创建另一个画布的情况下执行此操作,如ctx.drawImage(ctx.canvas,0,0); 将画布绘制到自身上,您可以在绘制时进行缩放. (14认同)
  • 但是这个尺度也会混淆坐标10 x是1.5*10.你如何弥补这一点 (3认同)

Cas*_*mor 17

我需要在没有putImageData()引起的插值的情况下完成它,所以我通过将图像数据缩放到一个新的,调整大小的ImageData对象来实现.我想不出任何其他时间我认为使用5个嵌套for循环是一个好主意:

function scaleImageData(imageData, scale) {
  var scaled = c.createImageData(imageData.width * scale, imageData.height * scale);

  for(var row = 0; row < imageData.height; row++) {
    for(var col = 0; col < imageData.width; col++) {
      var sourcePixel = [
        imageData.data[(row * imageData.width + col) * 4 + 0],
        imageData.data[(row * imageData.width + col) * 4 + 1],
        imageData.data[(row * imageData.width + col) * 4 + 2],
        imageData.data[(row * imageData.width + col) * 4 + 3]
      ];
      for(var y = 0; y < scale; y++) {
        var destRow = row * scale + y;
        for(var x = 0; x < scale; x++) {
          var destCol = col * scale + x;
          for(var i = 0; i < 4; i++) {
            scaled.data[(destRow * scaled.width + destCol) * 4 + i] =
              sourcePixel[i];
          }
        }
      }
    }
  }

  return scaled;
}
Run Code Online (Sandbox Code Playgroud)

我希望至少有一个其他程序员可以将这个复制并粘贴到他们的编辑器中,同时嘀咕着,"但是为了上帝的恩典,我去了."

  • @KvanTTT完全正确,虽然有时你想要那些厚实的像素. (3认同)
  • “c”变量指的是什么? (2认同)
  • @TomášZato 这是画布上下文 (2认同)

小智 17

我知道这是一个古老的主题,但由于人们喜欢它可能会发现它很有用,我将我的优化添加到rodarmor的代码中:

function scaleImageData(imageData, scale) {
    var scaled = ctx.createImageData(imageData.width * scale, imageData.height * scale);
    var subLine = ctx.createImageData(scale, 1).data
    for (var row = 0; row < imageData.height; row++) {
        for (var col = 0; col < imageData.width; col++) {
            var sourcePixel = imageData.data.subarray(
                (row * imageData.width + col) * 4,
                (row * imageData.width + col) * 4 + 4
            );
            for (var x = 0; x < scale; x++) subLine.set(sourcePixel, x*4)
            for (var y = 0; y < scale; y++) {
                var destRow = row * scale + y;
                var destCol = col * scale;
                scaled.data.set(subLine, (destRow * scaled.width + destCol) * 4)
            }
        }
    }

    return scaled;
}
Run Code Online (Sandbox Code Playgroud)

此代码使用较少的循环,运行速度大约快30倍.例如,对于100*100区域的100倍变焦,此代码需要250毫秒,而另一个需要超过8秒.


Six*_*ase 13

您可以使用drawImage方法缩放画布.

context = canvas.getContext('2d');
context.drawImage( canvas, 0, 0, 2*canvas.width, 2*canvas.height );
Run Code Online (Sandbox Code Playgroud)

这会将图像缩放到两倍大小,并将其西北部渲染到画布.使用drawImage方法的第三个和第四个参数来实现缩放,该方法指定图像的最终宽度和高度.

请参阅MDN上的文档https://developer.mozilla.org/en-US/docs/DOM/CanvasRenderingContext2D#drawImage%28%29