获取Canvas中的连通区域

  const url = './new_img.png';
    

    function getRegions(imageData, tolerance) {
      console.time('getRegions')
      var regions = []; // 存储所有区域的边界像素数组的数组
      var width = imageData.width;
      var height = imageData.height;
      var visited = new Array(width * height).fill(false); // 记录像素是否被访问过的数组

      // 获取像素值
      function getColor(x, y) {
        var index = (y * width + x) * 4;
        return [
          imageData.data[index],
          imageData.data[index + 1],
          imageData.data[index + 2]
        ];
      }

      // 计算像素之间的颜色差异
      function colorDifference(pixel1, pixel2) {
        var diff = 0;
        for (var i = 0; i < 3; i++) {
          diff += Math.abs(pixel1[i] - pixel2[i]);
        }
        return diff;
      }

      // 将像素添加到边界数组中
      function addToBoundary(region, x, y) {
        region.push({
          x: x,
          y: y
        });
        visited[y * width + x] = true; // 标记为已访问
      }

      // 开始区域生长算法
      for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
          if (!visited[y * width + x]) {
            var region = []; // 存储当前区域的边界像素
            var queue = [{
              x: x,
              y: y
            }]; // 存储当前区域的生长队列
            var seedColor = getColor(x, y);
            while (queue.length > 0) {
              var current = queue.shift();
              var currentColor = getColor(current.x, current.y);
              // 如果当前像素与种子像素相似,则将其添加到边界数组中,并将其周围的像素添加到队列中
              if (!visited[current.y * width + current.x] && colorDifference(currentColor, seedColor) <=
                tolerance) {
                addToBoundary(region, current.x, current.y);
                if (current.x > 0) queue.push({
                  x: current.x - 1,
                  y: current.y
                }); // 左
                if (current.x < width - 1) queue.push({
                  x: current.x + 1,
                  y: current.y
                }); // 右
                if (current.y > 0) queue.push({
                  x: current.x,
                  y: current.y - 1
                }); // 上
                if (current.y < height - 1) queue.push({
                  x: current.x,
                  y: current.y + 1
                }); // 下
              }
            }
            regions.push(region);
          }
        }
      }
      console.timeEnd('getRegions')
      return regions;
    }

    // 示例用法
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var canvas2 = document.getElementById('canvas2');
    var ctx2 = canvas2.getContext('2d');
    var img = new Image();
    img.src = url;

    img.onload = function () {
      canvas.width = img.width;
      canvas.height = img.height;
      canvas2.width = img.width;
      canvas2.height = img.height;
      ctx.drawImage(img, 0, 0);
      var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      var regions = getRegions(imageData, 10); // 10为容差值
      console.log('regions', regions)
      function randomColor() {
        var r = Math.floor(Math.random() * 256); // 0 到 255 之间的随机整数
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
        return "rgb(" + r + "," + g + "," + b + ")";
      }

      regions.forEach(function (region) {
        ctx2.fillStyle = randomColor();
        region.forEach(function (point) {
          ctx2.fillRect(point.x, point.y, 1, 1);
        });
      });
    };
  </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值