0

我正在为我的游戏引擎制作一些粒子动画,我想知道是否可以更改画布的 ImageElement 对象的hue、 gamma 和其他图像属性,从而保持图像的形状。

到目前为止,我尝试过的是:

_ctx.save();
_ctx.setStrokeColorHsl(240, 100, 50);
_ctx.fillRect(c.x, c.y, width, height);
_ctx.globalAlpha = nAlpha; //Modify the transparency
_ctx.drawImageScaled(p, c.x, c.y, width, height);
_ctx.restore();   

哪个有效,但它将色调应用于整个图像,这意味着如果图像是具有透明边缘的PNG,它甚至会绘制透明部分,因为它使用“fillRect()”(仅绘制矩形)到应用变换和图像对象。

结果是这样的:(红色颗粒是半透明的圆圈)

篝火晚会的尝试

有没有其他方法可以仅对图像形状进行着色或直接修改对象,以便转换仅适用于图像的可见部分?

4

2 回答 2

1

我不知道这样做的内置方法。您可以这样做的一种方法是将图像绘制到临时画布上并自己修改图像的像素。但是您需要在 RGB 和 HSL 之间转换的函数。您可以使用此方法对饱和度和亮度执行相同的操作。

double hue = 0.8;

var data = _context.getImageData(0, 0, _canvas.width, _canvas.height);
var pixels = data.data;
List<double> hsl;
List<int> newPixel;

for(var i = 0, len = pixels.length; i < len; i += 4) {
  hsl = rgbToHsl(pixels[i + 0], pixels[i + 1], pixels[i + 2]);

  newPixel = hslToRgb(h, hsl[1], hsl[2]);
  // or newPixel = hslToRgb((hsl[0] + hue) % 1.0, hsl[1], hsl[2]);

  pixels[i + 0] = newPixel[0];
  pixels[i + 1] = newPixel[1];
  pixels[i + 2] = newPixel[2];
}
_context.putImageData(data, 0, 0);

另一种方法,使用您的方法,可能是另外使用您的基本图像作为具有更改色调的画布的蒙版。您必须遍历像素并更改pixel[i + 3]为基本图像的 alpha。但是您不必在 HSL 和 RGB 之间进行转换。

于 2013-10-11T16:39:42.963 回答
1

您应该使用 globalCompositeOperation 模式。可能先画你的图像,然后是一个带有 globalAlpha 和 globalCompositeOperation = 'source-atop' 的 fillRect。

https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html

所以你可以玩转这些模式,使用打火机来使图像变亮和着色,或者使用目的地来添加背景。
但请注意,某些模式不适用于所有浏览器,几个月前我测试了较暗的模式,那时还不行。

于 2013-10-29T20:40:32.613 回答