最近,在小程序开发过程中,遇到了需要设置背景透明效果功能的需求。如果借助百度开放接口实现抠图功能是非常方便的,但是一个最大的缺点就是需要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