图片去除底色(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>
```