Jquery 计算HTML5画布上绘制的形状内的像素数?

Jquery 计算HTML5画布上绘制的形状内的像素数?,jquery,html,html5-canvas,Jquery,Html,Html5 Canvas,我使用HTML5画布动态绘制非常简单的形状 有没有办法计算画布上绘制的闭合形状内的像素数 以下是计算画布上非透明像素的方法 // get a reference to your canvas var c=document.getElementById("canvas"); var ctx=c.getContext("2d"); // get the pixel data from the canvas var imgData=ctx.getImageData(0,0,c.width,c.hei

我使用HTML5画布动态绘制非常简单的形状


有没有办法计算画布上绘制的闭合形状内的像素数

以下是计算画布上非透明像素的方法

// get a reference to your canvas
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");

// get the pixel data from the canvas
var imgData=ctx.getImageData(0,0,c.width,c.height);

// loop through each pixel and count non-transparent pixels
var count=0;
for (var i=0;i<imgData.data.length;i+=4)
  {
      // nontransparent = imgData.data[i+3]==0
      if(imgData.data[i+3]==0){ count++; }
  }
//获取对画布的引用
var c=document.getElementById(“画布”);
var ctx=c.getContext(“2d”);
//从画布获取像素数据
var imgData=ctx.getImageData(0,0,c.宽度,c.高度);
//循环遍历每个像素并计算不透明像素
var计数=0;
对于(var i=0;i
画布{边框:1px纯红;}
$(函数(){
//下面的洪水填充算法基于William Malone的优秀作品,版权2010 William Malone(www.williammone.com)——Apache许可证:http://www.apache.org/licenses/LICENSE-2.0 --除非适用法律要求或书面同意,否则根据许可证分发的软件按“原样”分发基础,无任何明示或暗示的保证或条件。有关许可证项下管辖权限和限制的特定语言,请参阅许可证。
var canvas=document.getElementById(“canvas”);
var context=canvas.getContext(“2d”);
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
var-strokeColor={r:0,g:0,b:0};
var-fillColor={r:101,g:155,b:65};
var数据;
var-strokeData;
函数重画(){
clearRect(0,0,画布宽度,画布高度);
putImageData(fillData,0,0);
提纲(上下文);
}
函数匹配StrokeColor(r、g、b、a){
//由于抗锯齿,必须检查是否接近黑色
返回(r+g+b<100&&a==255);
}
功能匹配StartColor(像素位置、startR、startG、startB){
var r=strokeData.data[pixelPos],
g=strokeData.data[pixelPos+1],
b=strokeData.data[pixelPos+2],
a=strokeData.data[pixelPos+3];
//如果轮廓图像的当前像素为黑色
if(匹配strokeColor(r、g、b、a)){
返回false;
}
r=fillData.data[pixelPos];
g=填充数据。数据[pixelPos+1];
b=fillData.data[pixelPos+2];
//如果当前像素与单击的颜色匹配
如果(r==startR&&g==startG&&b==startB){
返回true;
}
//如果当前像素与新颜色匹配
如果(r==fillColor.r&&g==fillColor.g&&b==fillColor.b){
返回false;
}
返回true;
}
函数setPixel(pixelPos、r、g、b、a){
fillData.data[pixelPos]=r;
fillData.data[pixelPos+1]=g;
fillData.data[pixelPos+2]=b;
fillData.data[pixelPos+3]=a!==未定义?a:255;
}
功能注水(startX、startY、startR、startG、startB){
var newPos;
var x;
变量y;
var-pixelPos;
var neighborLeft;
邻里关系;
var pixelStack=[[startX,startY]];
while(pixelStack.length){
newPos=pixelStack.pop();
x=newPos[0];
y=新位置[1];
//获取当前像素位置
pixelPos=(y*画布宽度+x)*4;
//只要颜色匹配并且在画布内,就可以向上移动
而(y>=0&&matchStartColor(像素点、startR、startG、startB)){
y-=1;
pixelPos-=画布宽度*4;
}
pixelPos+=画布宽度*4;
y+=1;
邻里关系=假;
邻里关系=错误;
//只要颜色匹配,就在画布内向下移动
while(y0){
if(匹配StartColor(像素位置-4、startR、startG、startB)){
如果(!Neightarleft){
//将像素添加到堆栈
pixelStack.push([x-1,y]);
邻里关系=正确;
}
}else if(邻里金融){
邻里关系=假;
}
}
如果(x<(画布宽度-1)){
if(匹配StartColor(像素位置+4、startR、startG、startB)){
如果(!邻居){
//将像素添加到堆栈
pixelStack.push([x+1,y]);
邻里关系=正确;
}
}else if(邻里关系){
邻里关系=错误;
}
}
pixelPos+=画布宽度*4;
}
}
}
//填满
功能油漆(startX、startY){
变量pixelPos=(星形*画布宽度+星形)*4,
r=fillData.data[pixelPos],
g=fillData.data[pixelPos+1],
b=填充数据。数据[pixelPos+2],
a=fillData.data[pixelPos+3];
如果(r==fillColor.r&&g==fillColor.g&&b==fillColor.b){
//这个已经满了
返回;
}
if(匹配strokeColor(r、g、b、a)){
返回;
}
漫灌(startX、startY、r、g、b);
重画();
}
函数init(){
var theShapes=document.getElementById(“theShapes”);
var theShapesContext=theShapes.getContext(“2d”);
绘图大纲(形状上下文);
提纲(上下文);
strokeData=context.getImageData(0,0,画布宽度,画布高度);
clearRect(0,0,context.canvas.width,context.canvas.height);
fillData=context.getImageData(0,0,画布宽度,画布高度);
$(“#画布”).mousedown(函数(e){
//鼠标下键位置
var mouseX=e.pageX-this.offsetLeft;
var mouseY=e.pageY-this.offsetTop;
paintAt(mouseX,mouseY);
});
重画();
};
函数drawOutline(上下文){
context.beginPath();
context.moveTo(55,60);
内容。贝塞尔曲线图(35,70,35,95,85,95);
Bezier Curveto(9511013011014095);
内容。贝塞尔曲线图(180,95,180,80,165,70);
内容。贝塞尔曲线图(185、40155、35140、45);
<!DOCTYPE html>
<html>
  <head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

//  The floodFill algorithm below is based on the good work by William Malone, Copyright 2010 William Malone (www.williammalone.com) -- Apache License: http://www.apache.org/licenses/LICENSE-2.0 -- Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

    var canvas=document.getElementById("canvas");
    var context = canvas.getContext("2d");
    var canvasWidth = canvas.width;
    var canvasHeight = canvas.height;
    var strokeColor =  {r: 0, g: 0, b: 0};
    var fillColor =  {r: 101,g: 155,b: 65};
    var fillData;
    var strokeData;

    function redraw() {
        context.clearRect(0, 0, canvasWidth, canvasHeight);
        context.putImageData(fillData, 0, 0);
        drawOutline(context);
    }

    function matchstrokeColor(r, g, b, a) {
      // must check for near black because of anti-aliasing
      return (r + g + b < 100 && a === 255);  
    }

    function matchStartColor(pixelPos, startR, startG, startB) {

      var r = strokeData.data[pixelPos],
        g = strokeData.data[pixelPos + 1],
        b = strokeData.data[pixelPos + 2],
        a = strokeData.data[pixelPos + 3];

      // If current pixel of the outline image is black-ish
      if (matchstrokeColor(r, g, b, a)) {
        return false;
      }

      r = fillData.data[pixelPos];
      g = fillData.data[pixelPos + 1];
      b = fillData.data[pixelPos + 2];

      // If the current pixel matches the clicked color
      if (r === startR && g === startG && b === startB) {
        return true;
      }

      // If current pixel matches the new color
      if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return false;
      }

      return true;
    }

    function setPixel(pixelPos, r, g, b, a) {
      fillData.data[pixelPos] = r;
      fillData.data[pixelPos + 1] = g;
      fillData.data[pixelPos + 2] = b;
      fillData.data[pixelPos + 3] = a !== undefined ? a : 255;
    }

    function floodFill(startX, startY, startR, startG, startB) {

      var newPos;
      var x;
      var y;
      var   pixelPos;
      var   neighborLeft;
      var   neighborRight;
      var   pixelStack = [[startX, startY]];

      while (pixelStack.length) {

        newPos = pixelStack.pop();
        x = newPos[0];
        y = newPos[1];

        // Get current pixel position
        pixelPos = (y * canvasWidth + x) * 4;

        // Go up as long as the color matches and are inside the canvas
        while (y >= 0 && matchStartColor(pixelPos, startR, startG, startB)) {
          y -= 1;
          pixelPos -= canvasWidth * 4;
        }

        pixelPos += canvasWidth * 4;
        y += 1;
        neighborLeft = false;
        neighborRight = false;

        // Go down as long as the color matches and in inside the canvas
        while (y <= (canvasHeight-1) && matchStartColor(pixelPos, startR, startG, startB)) {
          y += 1;

          setPixel(pixelPos, fillColor.r, fillColor.g, fillColor.b);

          if (x > 0) {
            if (matchStartColor(pixelPos - 4, startR, startG, startB)) {
              if (!neighborLeft) {
                // Add pixel to stack
                pixelStack.push([x - 1, y]);
                neighborLeft = true;
              }
            } else if (neighborLeft) {
              neighborLeft = false;
            }
          }

          if (x < (canvasWidth-1)) {
            if (matchStartColor(pixelPos + 4, startR, startG, startB)) {
              if (!neighborRight) {
                // Add pixel to stack
                pixelStack.push([x + 1, y]);
                neighborRight = true;
              }
            } else if (neighborRight) {
              neighborRight = false;
            }
          }

          pixelPos += canvasWidth * 4;
        }
      }
    }

    // Fill
    function paintAt(startX, startY) {

      var pixelPos = (startY * canvasWidth + startX) * 4,
        r = fillData.data[pixelPos],
        g = fillData.data[pixelPos + 1],
        b = fillData.data[pixelPos + 2],
        a = fillData.data[pixelPos + 3];

      if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        // this one's already filled
        return;
      }

      if (matchstrokeColor(r, g, b, a)) {
        return;
      }

      floodFill(startX, startY, r, g, b);

      redraw();
    }


    function init() {

      var theShapes=document.getElementById("theShapes");
      var theShapesContext=theShapes.getContext("2d");
      drawOutline(theShapesContext);

      drawOutline(context);

      strokeData = context.getImageData(0, 0, canvasWidth, canvasHeight);
      context.clearRect(0, 0, context.canvas.width, context.canvas.height);
      fillData = context.getImageData(0, 0, canvasWidth, canvasHeight);

      $('#canvas').mousedown(function (e) {
        // Mouse down location
        var mouseX = e.pageX - this.offsetLeft;
        var mouseY = e.pageY - this.offsetTop;
        paintAt(mouseX, mouseY);
      });

      redraw();
    };

    function drawOutline(theContext){   
        theContext.beginPath();
        theContext.moveTo(55, 60);
        theContext.bezierCurveTo(35,  70,  35, 95,  85, 95);
        theContext.bezierCurveTo( 95,110, 130,110, 140, 95);
        theContext.bezierCurveTo(180, 95, 180, 80, 165, 70);
        theContext.bezierCurveTo(185, 40, 155, 35, 140, 45);
        theContext.bezierCurveTo(130, 25,  95, 30,  95, 45);
        theContext.bezierCurveTo( 70, 25,  45, 30,  55, 60);
        theContext.closePath();
        theContext.rect(200,30,100,70);
        theContext.lineWidth = 3;
        theContext.strokeStyle = 'rgb(0,0,0)';
        theContext.stroke();        
    }

    function getFilledPixelCount(theContext,theCanvas){
        // get the pixel data from the fill canvas
        var imgData=theContext.getImageData(0,0,theCanvas.width,theCanvas.height);
        console.log(imgData.data.length);
        var count=0;
        for (var i=0;i<imgData.data.length;i+=4){
              r = imgData.data[i],
              g = imgData.data[i + 1],
              b = imgData.data[i + 2],
              a = imgData.data[i + 3];
              if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
                  count++;
              }
          }
        return(count);
    }

    $("#counter").click(function(){alert("There are "+getFilledPixelCount(context,canvas)+" filled pixels.");});

    init();

}); // end $(function(){});

</script>

  </head>
  <body>
        <p>The original stroked shapes</p>
        <canvas id="theShapes" width=350 height=150></canvas><br/>
        <p>The filled shapes used for pixel counting</p>
        <p>Click inside a shape below</p>
        <canvas id="canvas" width=350 height=150></canvas><br/>
        <button id="counter">Filled Count</button>
  </body>
</html>