编辑画布像素坐标

时间:2017-10-20 00:41:48

标签: javascript canvas

使用canvas js,如何编辑画布像素坐标? 试过

var pixelData = context.getImageData(0, 0, canvas.width, canvas.height);
    var length = pixelData.data.length;
    for (var i = 0; i < length; i += 4) {

        pixelData.data[i] = pixelData.data[i] * ratio;
        pixelData.data[i + 1] = pixelData.data[i + 1] * ratio;
        pixelData.data[i + 2] = pixelData.data[i + 2] * ratio;
    }
    console.log(pixelData);
    context.putImageData(pixelData, 0, 0);

它会改变像素的颜色。但需要改变坐标

1 个答案:

答案 0 :(得分:3)

您可以使用坐标做(字节数组)来计算缓冲区的位置:

pos = (y * width + x) << 2;    // << 2 = x4 but slightly faster + forces integer

或Uint32数组,要求您使用32位值写入单个像素:

pos = y * width + x

如果您需要使用位图方法而不是使用路径,则可以在单个操作中获取整个位图,将像素绘制到该位图上,最后“#34; commit&#34;回到画布,也是一次操作。为此,建议编写包装器:

function getBitmap(ctx) {
  let idata = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
  return {
    imageData: idata,
    buffer32 : new Uint32Array(idata.data.buffer)    // just a view/reference
  }
}

承诺:

function commit(ctx, bitmap) {
  ctx.putImageData(bitmap.imageData, 0, 0)
}

然后设置一个像素你可以使用这样的东西(为便于阅读而写的例子):

function setPixel(bitmap, x, y, r, g, b, a = 255) {  // = 255 for ES6 code, remove otherwise
  let pixel = a << 24 | b << 16 | g << 8 | r;        // make 32-bit value of ABGR
  let pos = (y * bitmap.imageData.width + x)|0;      // calc. position, force integer
  bitmap.buffer32[pos] = pixel;                      // set pixel in buffer
}

所有这一切的原因不仅仅是结构,而是您可以在以后轻松重写这些函数来代替路径操作。

&#13;
&#13;
const ctx = c.getContext("2d");
const r = Math.random;  // just to simplify example loop

// obtain the bitmap
const bmp = getBitmap(ctx);

// draw something
for(let i = 0, ra = 300; i < 21; i += 0.01) {
  setPixel(
    bmp,                       // bitmap
    (160+ra*Math.cos(i))|0,    // x
    (100+ra*Math.sin(i))|0,    // y
    255*r(), 255*r(), 255*r()  // r, g, b [,a]
  );
  ra *= 0.997;
}

// commit changes
commit(ctx, bmp);

function getBitmap(ctx) {
  let idata = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
  return {
    imageData: idata,
    buffer32 : new Uint32Array(idata.data.buffer)    // just a view/reference
  }
}

function commit(ctx, bitmap) {
  ctx.putImageData(bitmap.imageData, 0, 0)
}

function setPixel(bitmap, x, y, r, g, b, a = 255) {  // = 255 for ES6 code, remove otherwise
  let pixel = a << 24 | b << 16 | g << 8 | r;        // make 32-bit value of ABGR
  let pos = (y * bitmap.imageData.width + x)|0;      // calc. position, force integer
  bitmap.buffer32[pos] = pixel;                      // set pixel in buffer
}
&#13;
#c {border:1px solid; background:#000}
&#13;
<canvas id=c width=320 height=320></canvas>
&#13;
&#13;
&#13;

或者您可以使用前面提到的路径方法,但这只能一次绘制一种颜色,除非您想直接填充每个像素,这可能比一次填充所有像素慢:

ctx.beginPath();

// draw all pixels here using integer positions for x and y
ctx.rect(x, y, 1, 1);

// and finally fill in current fill style
ctx.fill();

或者如果您需要直接绘制每个像素;

ctx.fillStyle = pixelColor;
ctx.fillRect(x, y, 1, 1);