图片底色去除vue+canvas(简易版)

图片去除底色(vue+canvas)

把它封装成一个组件
首先要创建两个canvas标签
id(originalPic)处理图片的画布
id (modify) 存放处理图片后的画布

  <template>
	<div class="img-warpper">
      <img v-if="!flag" :src="imageSrc" />
      <canvas style="display: none;" id="originalPic"></canvas>
      <canvas style="display: none;" ref="modify" v-show="flag" id="modify"></canvas>
      <button class="cancle" @click="removeBgc()">点击去底色</button>
    </div>
  </template>
	<script>
	    data() {
		    return {
		      cimg: { //图片的宽高
		        width: 0,
		        height: 0
		      },
		      	flag: false //控制是否显示预览图(imageSrc)去底色后不显示预览图
		    }
		},
	    props: {
	    	imageSrc:  {//默认展示的预览图地址
	    		type: String,
	    		default() {
	    			return ""
	    		}
	    	}
		},
		methods: {
			removeBgc() {
			    	var _this = this
					//1.获取画布
					var cavs = document.querySelector("#Originalpic");
			    	var picCavs = document.querySelector("#modify");
			    	var canvasResult = cavs.getContext("2d");
			    	var contextResult = picCavs.getContext("2d");
			    	//2.每次去底色前清空画布
			    	picCavs.getContext("2d").clearRect(0, 0, this.cimg.width, this.cimg.height);
			    	var imgData = [],imgDataResult = [],rgbaPicker = []; //依次为图片像素信息 处理完成后的像素信息 最终颜色值(rgba)
			    	var img = new Image();
        	    	img.crossOrigin = "anonymous"; //处理图片跨域
       				img.src = this.imageSrc + "&v=" + Math.random(); //防止图片缓存
       				img.onload = function() {
          			cavs.setAttribute("width", img.width); //设置画布宽度
          			cavs.setAttribute("height", img.height); //设置画布高度
          			picCavs.setAttribute("width", img.width); //同上
          			picCavs.setAttribute("height", img.height); //同上
		        	_this.cimg.width = img.width; //将图片宽度赋值cimg中 用于下次清除画布
          			_this.cimg.height = img.height;  //将图片高度赋值cimg中 用于下次清除画布
          			canvasResult.drawImage(this, 0, 0);//将图像绘制到画布上 
          			imgData = canvasResult.getImageData(0, 0, img.width, img.height);// 获取像素信息数据(原数据)
          			imgDataResult = imgData; // 赋值像素信息数据(要修改的数据)
          			//points  (获取画布点坐标[ x, y ])
          			var points = [ [1, 1],[img.width - 1, 1],[img.width / 2, 1],[img.width/2, img.height - 1],[1, img.height - 1],[1, img.height / 2],[img.width - 1, img.height / 2],[img.width - 1, img.height - 1] ];
          			for (var i = 0; i <= points.length - 1; i++) {
          		   		//遍历坐标获取对应点RGBA()  getImageData()
            			rgbaPicker[i] = canvasResult.getImageData(points[i][0],points[i][1],1,1).data; //获取
          			}
          			var obj = {};
          			var range = 2;//容差值
          			var maxCount = 0; //rgba中0-255
          			var maxElement = rgbaPicker[0]; //默认取第一个rgba
          			for (var i = 0; i < rgbaPicker.length; i++) {
            			var ponit = rgbaPicker[i];
           				var key = ponit.join(",");
            			obj[key] = 0;
            			//对色点附近点位也做计数
            			for (var j = 0; j < rgbaPicker.length; j++) {
              				if (
                				Math.abs(ponit[0] - rgbaPicker[j][0]) <= range &&
                				Math.abs(ponit[1] - rgbaPicker[j][1]) <= range &&
                				Math.abs(ponit[2] - rgbaPicker[j][2]) <= range
              				) {
                				obj[key]++;
             	  			}
            			}

            			if (maxCount < obj[key]) {
              				maxCount = obj[key];
              				maxElement = key;
            			}
          			}
          			if (maxCount <= 1) {
          					_this.flag = false
            				//色点太多无法计算
          				} else {
            			var rgba = maxElement.split(",").map(Number);
          			}
         			// 容差大小
          			var tolerance = range * range * range;
          			// 基于原始图片数据处理
          			for (var index = 0; index < imgData.data.length; index += 4) {
            			var r = imgData.data[index];
            			var g = imgData.data[index + 1];
           				var b = imgData.data[index + 2];

            			if (
              				Math.sqrt(
                			(r - rgba[0]) * (r - rgba[0]) +
                  			(g - rgba[1]) * (g - rgba[1]) +
                  			(b - rgba[2]) * (b - rgba[2])
              				) <= tolerance
            			) {
            			  //将rgba赋值0
              				imgDataResult.data[index] = 0;
              				imgDataResult.data[index + 1] = 0;
              				imgDataResult.data[index + 2] = 0;
              				imgDataResult.data[index + 3] = 0;
            			} else {
              				imgDataResult.data[index] = r;
              				imgDataResult.data[index + 1] = g;
              				imgDataResult.data[index + 2] = b;
              				imgDataResult.data[index + 3] = imgData.data[index + 3];
            			}
          			}
          			contextResult.putImageData(imgDataResult, 0, 0); //将图像数据放回画布
          			this.$refs.modify.style.display = 'block' //处理完成将画布展示
          			this.flag = true
        		};
			}
		}
	</script>
    ```

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen_CV

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值