尝试用一个图像来遮罩另一个图像,然后对结果中的像素颜色进行统计,但统计结果不正确
我用一个黑色圆形作为一个100×100的红色矩形的遮罩,总像素数为10,000。遮罩效果很好,能得到一个漂亮的红色圆形,但当我尝试统计结果中的所有红色像素时,得到的是10,000(原始矩形),而我应该得到一个更小的数值(来自圆形的像素)。
我知道需要把遮罩以某种方式扁平化,我也找到了若干做法的示例,但都不起作用。为了避免在这个示例里把我尝试过的所有方法都堆砌在一起,我就只解释问题,我觉得再多写几行代码就可以解决。
window.addEventListener("load", (event) => {
console.log("Page is fully loaded");
init();
});
function init() {
//var myCanvas = document.querySelector("#myCanvas");
var redColorCount=0;
var stage = new createjs.Stage("myCanvas");
// 1. Create your masked graphic (or container)
var shape = new createjs.Shape();
shape.graphics.beginFill("red").drawRect(0, 0, 100, 100); // Red Square
var maskShape = new createjs.Shape();
maskShape.graphics.beginFill("#000").drawCircle(50, 50, 50); //Black Circle for mask
console.log(maskShape.x);
shape.mask = maskShape;
shape.cache(0, 0, 100, 100);
var cacheCanvas = shape.cacheCanvas;
var ctx = cacheCanvas.getContext("2d");
var imageData = ctx.getImageData(0, 0, 100, 100).data;
console.log(imageData);
stage.addChild(shape);
shape.uncache();
stage.update();
console.log("Length: "+imageData.length);
for (var i = 0; i < imageData.length; i += 4) {
if ((imageData[i] == 255) && (imageData[i+1] == 0) && (imageData[i+2] == 0)){
redColorCount++;
}
}
console.log("redColorCount: "+redColorCount);
}
<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<canvas id="myCanvas" width="500" height="350"></canvas>
解决方案
正如Yogi在注释中所说的,这里不需要 create.js 包装器来实现你想要的效果。
标准的Canvas API就足够了,它的用法就像使用create.js一样简单。
现在,考虑到你正处在一个庞大的代码库中,无法全部改动,并且鉴于我已经对create.js的源代码深入研究过,下面给出一个临时的解决方案。
首先,似乎没有一种简单的方法(一个选项或一个函数调用)可以让 shadowCanvas 应用 mask。对于主画布,遮罩是通过下述方法应用的
shape.updateContext
(由 Shape 从 DisplayObject 继承)在 shape.draw 之前,在清空的画布上被调用。
因此,为了让阴影画布应用遮罩,你需要对它进行操作,超出其作用域:
// ..........
shape.cache(0, 0, 100, 100);
var cacheCanvas = shape.cacheCanvas;
var ctx = cacheCanvas.getContext("2d"); // original code up to here
ctx.clearRect(0, 0, 100, 100);
shape.updateContext(ctx);
shape.updateCache();
var imageData = ctx.getImageData(0, 0, 100, 100).data; // back to original code
// .........
堆栈片段:
window.addEventListener("load", (event) => {
//console.log("Page is fully loaded");
init();
});
function init() {
//var myCanvas = document.querySelector("#myCanvas");
var redColorCount=0;
var stage = new createjs.Stage("myCanvas");
// 1. Create your masked graphic (or container)
var shape = new createjs.Shape();
shape.graphics.beginFill("red").drawRect(0, 0, 100, 100); // Red Square
var maskShape = new createjs.Shape();
maskShape.graphics.beginFill("#000").drawCircle(50, 50, 50); //Black Circle for mask
shape.mask = maskShape;
shape.cache(0, 0, 100, 100);
var cacheCanvas = shape.cacheCanvas;
// document.body.appendChild(cacheCanvas);
var ctx = cacheCanvas.getContext("2d");
ctx.clearRect(0, 0, 100, 100);
shape.updateContext(ctx);
shape.updateCache();
var imageData = ctx.getImageData(0, 0, 100, 100).data;
//console.log(imageData);
stage.addChild(shape);
shape.uncache();
stage.update();
for (var i = 0; i < imageData.length; i += 4) {
if ((imageData[i] == 255) && (imageData[i+1] == 0) && (imageData[i+2] == 0) && (imageData[i+3] >= 128)){
redColorCount++;
}
}
console.log("redColorCount: "+redColorCount+" Length: "+imageData.length);
}
<canvas id="myCanvas" width="200" height="110"></canvas>
<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
更新:当然,总有一种办法可以使用主画布从(var ctx = myCanvas.getContext("2d"))获取 ImageData,但那很显然,可能不是你需要的。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。