当前位置:   article > 正文

使用js实现证件照p图,背景扣除和替换,完全开源!!!!_js 抠图

js 抠图

概述

不知道大家有没有被网上的一些付费软件恶心到,昨天本来想p个证件照背景颜色,百度一打开,全是说的免费,一点进去,修好背景之后,下载就要开始付费了。于是我写了以下代码,大家放心,完全免费开源,需要的自取

实现效果

js实现证件照背景色替换

源代码

随便新建一个文件为index.html,将代码复制进去,保存然后双击,即可使用,源码如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="file" id="fileDom" />
    <canvas width="150" height="150"></canvas>
    颜色:
    <input type="color" id="self_color" />
    &nbsp 透明度(0-255,0表示透明,255表示不透明)<input type="number" id="self_op" />
    <button id="confirm">确认</button>
    <button id="exp">导出</button>
  </body>
  <script>
    const cvs = document.querySelector("canvas");
    const btn = document.querySelector("#confirm");
    const exp = document.querySelector("#exp");
    const selfColor = document.querySelector("#self_color");
    const selfOp = document.querySelector("#self_op");
    const fileDom = document.querySelector("#fileDom");
    let opitityNum = 255;
    let greenColor = [220, 190, 190, 255];

    let ctx = cvs.getContext("2d", {
      willReadFrequently: true,
    });
    let originalImageData;
    function init(src) {
      if (!src) {
        return;
      }
      const img = new Image();
      img.crossOrigin = "";
      img.src = src || "";
      img.onload = () => {
        cvs.width = img.width;
        cvs.height = img.width;
        ctx = cvs.getContext("2d", {
          willReadFrequently: true,
        });
        ctx.drawImage(img, 0, 0);
        originalImageData = ctx.getImageData(0, 0, img.width, img.width);
      };
    }
    function confirm() {
      ctx.putImageData(imgData, 0, 0);
      originalImageData = ctx.getImageData(0, 0, cvs.width, cvs.height);
    }
    function exportImg() {
      var imgDataURL = cvs.toDataURL();
      var a = document.createElement("a");
      a.href = imgDataURL;
      a.download = "image.png";
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    }
    init();
    let imgData = ctx.getImageData(0, 0, cvs.width, cvs.height);
    btn.onclick = confirm;
    exp.onclick = exportImg;
    selfOp.onchange = function () {
      opitityNum = selfOp.value;
      cvs.click();
    };
    selfColor.onchange = () => {
      cvs.click();
    };
    fileDom.onchange = async (e1) => {
      let file = await fileToBase64(e1.target.files[0]);
      init(file);
    };
    cvs.addEventListener("click", (e) => {
      greenColor = conversion(selfColor.value);
      const x = e.offsetX;
      const y = e.offsetY;
      if (!originalImageData) {
        console.error("原始图像数据未初始化!");
        return;
      }
      ctx.putImageData(originalImageData, 0, 0);
      imgData = ctx.getImageData(0, 0, cvs.width, cvs.height);
      const clickColor = getColor(x, y, imgData);
      const stack = [{ x, y }];
      while (stack.length > 0) {
        const { x, y } = stack.pop();
        if (x < 0 || x >= cvs.width || y < 0 || y >= cvs.height) {
          continue;
        }
        const i = point2Index(x, y);
        const color = getColor(x, y, imgData);
        if (diff(color, clickColor) && diff1(color, greenColor) !== 0) {
          imgData.data.set(greenColor, i);
          stack.push({ x: x + 1, y });
          stack.push({ x: x - 1, y });
          stack.push({ x, y: y + 1 });
          stack.push({ x, y: y - 1 });
        }
      }
      ctx.putImageData(imgData, 0, 0);
    });
    function fileToBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function () {
          const base64String = reader.result.split(",")[1];
          resolve(reader.result);
        };
        reader.onerror = function () {
          reject(new Error("Failed to load file"));
        };
      });
    }
    function point2Index(x, y) {
      return (y * cvs.width + x) * 4;
    }
    function conversion(value) {
      let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
      let color = value.toLowerCase();
      if (reg.test(color)) {
        if (color.length === 4) {
          let colorNew = "#";
          for (let i = 1; i < 4; i += 1) {
            colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
          }
          color = colorNew;
        }
        let colorChange = [];
        for (let j = 1; j < 7; j += 2) {
          colorChange.push(parseInt("0x" + color.slice(j, j + 2)));
        }
        colorChange.push(opitityNum);
        return colorChange;
      } else {
        return color;
      }
    }
    function getColor(x, y, imageData) {
      const i = point2Index(x, y);
      return [
        imageData.data[i],
        imageData.data[i + 1],
        imageData.data[i + 2],
        imageData.data[i + 3],
      ];
    }
    function diff1(color1, color2) {
      const res =
        Math.abs(color1[0] - color2[0]) +
        Math.abs(color1[1] - color2[1]) +
        Math.abs(color1[2] - color2[2]) +
        Math.abs(color1[3] - color2[3]);
      return res;
    }
    function diff(color1, color2, tolerance = 30) {
      const rDiff = Math.abs(color1[0] - color2[0]);
      const gDiff = Math.abs(color1[1] - color2[1]);
      const bDiff = Math.abs(color1[2] - color2[2]);
      return rDiff <= tolerance && gDiff <= tolerance && bDiff <= tolerance;
    }
  </script>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/228139
推荐阅读
相关标签
  

闽ICP备14008679号