0

我正在尝试将文本绘制到具有特定 alpha 级别的画布上,然后剪辑文本并使用它自己的 alpha 级别绘制背景颜色:

ctx.globalCompositeOperation = '...';
    ctx.fillStyle = 'rgba(' + fgcolor.r + ', ' +  fgcolor.g + ', ' + fgcolor.b + ',' + (fgcolor.a / 255.0) + ')';
       ctx.fillText(String.fromCharCode(chr), x,y);
ctx.globalCompositeOperation = '...';
    ctx.fillStyle = 'rgba(' + bgcolor.r + ', ' +  bgcolor.g + ', ' + bgcolor.b + ',' + (bgcolor.a / 255.0) + ')';
    ctx.fillRect(x, y, chr_width, chr_height);

我试过玩 globalCompositeOperation 和 beginPath 但我无法达到预期的结果。我还想避免 drawImage 和屏幕外画布,因为速度是一个主要问题。

4

2 回答 2

1

此函数将 RGBA 颜色转换为 RGB:

function RGBAtoRGB(r, g, b, a, backgroundR,backgroundG,backgroundB){
  var r3 = Math.round(((1 - a) * backgroundR) + (a * r))
  var g3 = Math.round(((1 - a) * backgroundG) + (a * g))
  var b3 = Math.round(((1 - a) * backgroundB) + (a * b))
  return "rgb("+r3+","+g3+","+b3+")";
}  
  1. 将背景 RGBA 转换为 RGB,并用 RGB 填充背​​景。

  2. 将前景 RGBA 转换为 RGB,并用 RGB 填充前景文本。

于 2015-03-17T23:58:16.740 回答
0

这正是我想要做的:

                  ctx.clearRect(x, y, chr_width, chr_height);
                 ctx.save();
            ctx.beginPath();
            ctx.rect(x, y, chr_width, chr_height);
            ctx.clip();     

            if (fgcolor.a != 255) {
                ctx.fillStyle = 'rgba(' + fgcolor.r + ', ' +  fgcolor.g + ', ' + fgcolor.b + ',' + (fgcolor.a / 255.0) + ')';

                ctx.fillText(String.fromCharCode(chr), x,y);

                var imgData=ctx.getImageData(x,y,chr_width,chr_height);
                for (var idx = 0; idx < imgData.data.length; idx+=4) {
                    if (! imgData.data[idx+3]) {
                        imgData.data[idx] = bgcolor.r;
                        imgData.data[idx+1] = bgcolor.g;
                        imgData.data[idx+2] = bgcolor.b;
                        imgData.data[idx+3] = bgcolor.a;
                    }
                }

                ctx.putImageData(imgData,x,y);
            }
            else {
                ctx.fillStyle = 'rgba(' + bgcolor.r + ', ' +  bgcolor.g + ', ' + bgcolor.b + ',' + (bgcolor.a / 255.0) + ')';   
                ctx.fillRect(x, y, chr_width, chr_height);
                ctx.fillStyle = 'rgba(' + fgcolor.r + ', ' +  fgcolor.g + ', ' + fgcolor.b + ',' + (fgcolor.a / 255.0) + ')';
                ctx.fillText(String.fromCharCode(chr), x,y);

            }

            ctx.globalAlpha = 1.0;

            ctx.globalCompositeOperation = 'source-over';

            ctx.restore();

有没有更快的方法来避免直接访问数据?谢谢。

于 2015-03-18T14:42:53.937 回答