最近,在小程序开发过程中,遇到了需要设置背景透明效果功能的需求。如果借助百度开放接口实现抠图功能是非常方便的,但是一个最大的缺点就是需要money支持。不得已,参考网上各家代码,实现了借助canvas来实现纯色背景抠图功能。只是非常简单的一个应用,先看效果:
好,下面我们来梳理下逻辑,同时完成代码的编写。
一、实现逻辑
1、准备好一张纯色背景的图片(我设置的剔除白色背景的)。
2、把该图片绘制到canvas上(保持大小比例不变)。
3、对canvas上的每个像素进行扫描,把像素是白色背景的透明度设置为透明
4、把设置完成的图像再重新绘制到canvas上
5、完成。背景色设置成透明。
二、代码实现
现在根据实现逻辑,我们来编写代码,具体如下:
1、在wxml文件中,添加canvas标签。(class样式不展示了,这是自定义的)
<canvas id="myCanvas" type="2d" class="mv-cvs"></canvas>
2、添加一个按钮事件,来实现剔除图片背景颜色。
<button bindtap="clickBgd">背景透明</button>
3、在clickBgd中编写抠图代码:
clickBgd() {
wx.createSelectorQuery()
.select('#myCanvas') // 在 WXML 中填入的 id
.fields({ node: true, size: true })
.exec((res) => {
// Canvas 对象
const canvas = res[0].node
// 渲染上下文
const ctx = canvas.getContext("2d")
const image = canvas.createImage()
// const dpr = wx.getSystemInfoSync().pixelRatio
let that = this
// 图片加载完成回调
image.onload = () => {
// 将图片绘制到 canvas 上
let width = 300
let height = 150
console.log("width2:", width, ",height2:", height);
ctx.drawImage(image, 0, 0, width, height)
const imgDt = ctx.getImageData(0, 0, width, height)
const data = imgDt.data
for (let i = 0; i < data.length; i += 4) {
let r = data[i + 0]
let g = data[i + 1]
let b = data[i + 2]
data[i + 0] = 255
data[i + 1] = 0
data[i + 2] = 0
if ([r, g, b].every(v => v > 80 && v < 256)) {
data[i + 3] = 0
}
}
//清除画布之前的图片
ctx.clearRect(0, 0, 360, 360)
//创建新的图片数据
let nimgdt = canvas.createImageData(data, width, height)
ctx.putImageData(nimgdt, 0, 0)
//转成png格式的图片
let dtUrl = canvas.toDataURL("image/png")
console.log("dataurl:", dtUrl);
that.setData({
imgsrc: dtUrl,
})
}
// 设置要剔除背景色的图片src
image.src ="picture.jpg";
})
},
三、完整代码
具体完整代码链接:https://download.csdn.net/download/m0_60318025/87894106