【问题标题】:How to overlay non-transparent part of Bitmap with a color in Easeljs/Createjs?如何在 Easeljs/Createjs 中用颜色覆盖位图的不透明部分?
【发布时间】:2017-07-14 14:37:06
【问题描述】:

我有一个带有一些透明部分的 PNG 图像。现在我想在图像的非透明部分应用颜色叠加,同时保持透明部分不变。

如果我使用ColorFilter,它会填满整个位图。我也尝试过AlphaMaskFilter(使用与源相同的PNG),但它也不起作用。整个位图总是充满颜色。

关于如何做的任何其他建议?

【问题讨论】:

    标签: canvas html5-canvas createjs easeljs


    【解决方案1】:

    您必须编写一个过滤器:

    • 与 AlphaMaskFilter 类似,仅使用 rect()source-out 复合操作 OR
    • 与 AlphaMapFilter 类似,但它会在源图像中遇到空像素的地方绘制一个彩色像素。

    这是使用上述第一种方法的示例插件,这可能是最有效的:

    (function () {
        "use strict";
        function ColorMaskFilter(color) {
            this.color = color;
        }
        var p = createjs.extend(ColorMaskFilter, createjs.Filter);
        p.applyFilter = function (ctx, x, y, width, height, targetCtx, targetX, targetY) {
            if (!this.color) { return true; }
            targetCtx = targetCtx || ctx;
            if (targetX == null) { targetX = x; }
            if (targetY == null) { targetY = y; }
    
            targetCtx.save();
            if (ctx != targetCtx) {
                return false;
            }
    
            targetCtx.globalCompositeOperation = "source-out"; // Use source-in to fill the shape instead
        targetCtx.fillStyle = this.color;
            targetCtx.rect(targetX,targetY,width,height);
        targetCtx.fill();
    
            targetCtx.restore();
            return true;
        };
        p.clone = function () {
            return new AlphaMaskFilter(this.color);
        }; 
        createjs.ColorMaskFilter = createjs.promote(ColorMaskFilter, "Filter");
    }());
    

    我用这个例子做了一个快速的小提琴:http://jsfiddle.net/dbtwd463/

    注意:根据原文编辑,仅建议包含样本和小提琴的方法

    【讨论】:

    • 您好,感谢您的回答。根据您的建议,我在下面发布了ColorMaskFilter 过滤器。它似乎按预期工作,但如果您也可以看看,我将不胜感激。
    • 您的方法应该没问题——但这里有一个基于 AlphaMaskFilter 的更简单的方法。 jsfiddle.net/dbtwd463
    • 谢谢。非常感谢您的投入和时间。我将您的答案标记为已接受的答案。当您有机会时,请按照 SO 的建议使用小提琴的复制粘贴来更新您的答案。
    【解决方案2】:

    根据 Lanny 的建议,我可以想出这个过滤器。

    <script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
    
    <canvas id="canvas" width="50" height="50" style="border:1px solid red; background: pink">
            no canvas!
        </canvas>
    
    <script>
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext("2d");
      var stage = new createjs.Stage(canvas);
    
      function init(img) {
        var bmp = new createjs.Bitmap(img);
        stage.addChild(bmp);
        
        bmp.filters = [new createjs.ColorMaskFilter('#ffff00')];
        bmp.cache(0, 0, 30, 30);
    
        stage.update();
      }
    
      (function() {
        "use strict";
    
        function ColorMaskFilter(color) {
          this.color = color;
        }
    
        var p = createjs.extend(ColorMaskFilter, createjs.Filter);
    
        p.applyFilter = function(ctx, x, y, width, height, targetCtx, targetX, targetY) {
          targetCtx = targetCtx || ctx;
          if (targetX == null) {
            targetX = x;
          }
          if (targetY == null) {
            targetY = y;
          }
    
          targetCtx.save();
          if (ctx != targetCtx) {
            // TODO: support targetCtx and targetX/Y
            // clearRect, then draw the ctx in?
            return false;
          }
    
          if (!this.mask || this.mask.width != width || this.mask.height != height) {
            var shape = new createjs.Shape();
            shape.graphics.beginFill(this.color || '#ff0000');
            shape.graphics.drawRect(0, 0, width, height);
            shape.cache(0, 0, width, height);
    
            this.mask = shape.cacheCanvas;
          }
    
          targetCtx.globalCompositeOperation = "source-in";
          targetCtx.drawImage(this.mask, targetX, targetY);
          targetCtx.restore();
          return true;
        };
    
        /** docced in super class **/
        p.clone = function() {
          return new ColorMaskFilter(this.color);
        };
    
        /** docced in super class **/
        p.toString = function() {
          return "[ColorMaskFilter]";
        };
    
    
        createjs.ColorMaskFilter = createjs.promote(ColorMaskFilter, "Filter");
      }());
    </script>
    
    <hr>Source: <img width="30" height="30" onload="init(this)" title="" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzA5OUIxQjFGQUM5MTFFNjlCRDRBMjM4Qzg2RDM5M0EiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzA5OUIxQjJGQUM5MTFFNjlCRDRBMjM4Qzg2RDM5M0EiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3MDk5QjFBRkZBQzkxMUU2OUJENEEyMzhDODZEMzkzQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3MDk5QjFCMEZBQzkxMUU2OUJENEEyMzhDODZEMzkzQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pkob9IwAAAB0SURBVHjaYmT4X/GfYQAAE8MAARYY4z9DOyM9LGRkqPw/oD4e+KCGgcN2S+WA1ENqW2R7KJpxUPh48AQ1vuAhBwCj7v+g8vGoxaMWj1o8avGoxdSpJHAV8KNBTZWgBtbBj8CNwdFUTfX29UjrwgyYxQABBgBraRUTSfHtgAAAAABJRU5ErkJggg=="
    />

    【讨论】:

      【解决方案3】:

      感谢 Supersan 和 Lanny 的回答!

      不幸的是,过滤器似乎不再适用于最新版本的 createjs :-(

      我更新了 jsfiddle 示例:http://jsfiddle.net/rqbf3th4/1/

      我刚刚更新了 createjs (v 1.0.0),现在不再应用过滤器:-(

      有人可以帮忙吗?

      (function () {
          "use strict";
          function ColorMaskFilter(color) {
              this.color = color;
          }
          var p = createjs.extend(ColorMaskFilter, createjs.Filter);
          p.applyFilter = function (ctx, x, y, width, height, targetCtx, targetX, targetY) {
              if (!this.color) { return true; }
              targetCtx = targetCtx || ctx;
              if (targetX == null) { targetX = x; }
              if (targetY == null) { targetY = y; }
       
              targetCtx.save();
              if (ctx != targetCtx) {
                  return false;
              }
       
              targetCtx.globalCompositeOperation = "source-in"; // Use source-in to fill the shape instead
          targetCtx.fillStyle = this.color;
              targetCtx.rect(targetX,targetY,width,height);
          targetCtx.fill();
          
              targetCtx.restore();
              return true;
          };
          p.clone = function () {
              return new AlphaMaskFilter(this.color);
          }; 
          createjs.ColorMaskFilter = createjs.promote(ColorMaskFilter, "Filter");
      }());
      
      
      
      
      
      var stage = new createjs.Stage("canvas");
      var img = document.createElement("img");
      img.crossOrigin = "Anonymous";
      var bmp = new createjs.Bitmap(img);
      img.onload = function() {
              bmp.filters = [new createjs.ColorMaskFilter("#ff0000")];
          bmp.cache(0,0,img.width, img.height);
          stage.addChild(bmp);
          stage.update();
      }
      img.src = "http://playpen.createjs.com/CORS/duck.png";
      

      【讨论】:

      • 嘿@user14999882,您最好使用此信息更新您的问题,而不是将其添加为可能的答案。
      • 我试图这样做,但 stackoverflow 不允许我这样做(新帐户):-( 现在它似乎工作正常......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多