1

在画布中缩放 alpha 值的最佳方法是什么?

我要解决的第一个问题是绘制一个具有固有低 alpha 值的精灵。我想把它画得比实际亮度高 3-4 倍。目前我只是在同一个地方画了4次。(我无法编辑图像文件并且globalAlpha不超过 1)

我要解决的第二个问题是绘制多个重叠精灵的边界。精灵是圆形的,但带有曲线。我想我会将此方法与 结合使用globalCompositeOperation = 'destination-out',但为此我需要最大化第二张绘图的 alpha 值。

4

2 回答 2

1

作为 markE 答案的一个选项 - 您可以直接缩放 alpha 通道。

我只推荐这种方法作为预处理阶段的一部分,而不是每次需要使用精灵时都使用这种方法,因为以这种方式迭代缓冲区是一个相对较慢的过程。

现场演示在这里

来自演示的快照

假设您已经在画布中有精灵并且知道它的位置:

/// get the image data and cache its pixel buffer and length
var imageData = context.getImageData(x, y, width, height);
var data = imageData.data;
var length = data.length;
var i = 0;

var scale = 4; /// scale values 4 times. This may be a fractional value

/// scale only alpha channel
for(; i < length; i += 4) {
    data[i + 3] *= scale;
}

context.putImageData(imageData, x, y);

画布使用钳制和舍入值的好处Uint8ClampedArray是您无需检查下限或上限,也无需将值转换为整数 - 内部代码您完成所有这些工作。

于 2013-10-16T23:54:23.350 回答
1

您可以通过将 rgba 颜色展平为 rgb 然后增加 rgb 分量值来“增亮”rgba 颜色。

  • 将 rgba 值转换为 rgb,同时使背景颜色生效。
  • 将生成的红色、绿色、蓝色值增加一个百分比以“增亮”颜色。

这是一个执行此操作的函数(免责声明:此处未经测试的代码!):

function brighten(RGBA,bg,pct){

  // convert rgba to rgb

  alpha = 1 - RGBA.alpha/255;
  red = Math.round((RGBA.alpha*(RGBA.red/255)+(alpha*(bg.red/255)))*255);
  green = Math.round((RGBA.alpha*(RGBA.green/255)+(alpha*(bg.green/255)))*255);
  blue = Math.round((RGBA.alpha*(RGBA.blue/255)+(alpha*(bg.blue/255)))*255);

  // brighten the flattened rgb by a percentage (100 will leave the rgb unaltered)

  redBright=parseInt(  Math.min(255,red*pct/100) );
  greenBright=parseInt(  Math.min(255,green*pct/100) );
  blueBright=parseInt(  Math.min(255,blue*pct/100) );

  return({red:redBright,green:greenBright,blue:blueBright});

}    
于 2013-10-16T20:51:31.683 回答