注意:说明:
注意:此方案为旧版小程序接入方案,相对繁琐,但自由度较高。新版方案请参考 图片&照片美颜,接入流程更简单。
一、准备工作
·小程序开发入门请参见 微信小程序文档。
·请阅读 Web 美颜特效 SDK 接入指南,熟悉 SDK 基本用法。
二、步骤1:小程序后台配置域名白名单
2. 单击修改,配置以下域名并保存。
·请求域名:
https://webar.qcloud.com;https://webar-static.tencent-cloud.com;https://aegis.qq.com;以及鉴权签名接口(get-ar-sign)的地址
·downloadFile 域名:
https://webar-static.tencent-cloud.com
三、步骤2:安装并构建 npm
小程序 npm 相关请参见 小程序使用 npm。
1. 安装:进入 miniprogram 目录,执行 `npm install` 安装依赖。
npm install tencentcloud-webar
2. 构建:
打开小程序开发者工具,顶部菜单选择工具 > 构建 npm。构建成功后,会在 miniprogram/miniprogram_npm 文件夹下看到对应的构建产物。
3. 在 app.json 中配置 workers 路径:
"workers": "miniprogram_npm/tencentcloud-webar/worker"
四、步骤3:引入文件
import '../../miniprogram_npm/tencentcloud-webar/lib.js';import '../../miniprogram_npm/tencentcloud-webar/core.js';// 按需初始化3d插件,如果不需要3d则可以不引用import { plugin3d } from '../../miniprogram_npm/tencentcloud-webar/plugin-3d'// 导入 ArSdkimport { ArSdk } from "../../miniprogram_npm/tencentcloud-webar/index.js";import { default as localStorage } from '../../utils/localStorage';import sha256 from '../../utils/sha256';
五、步骤4:初始化 SDK
示例代码如下:
// wxml//打开相机,通过position使相机不展示<camera device-position="{{'front'}}" frame-size="large" flash="off" resolution="medium" style="width: 750rpx; height: 134rpx;position:absolute;top:-9999px;" />//sdk 将处理完的画面实时输出到此 canvas 上<canvas type="webgl" canvas-id="main-canvas" id="main-canvas" style="width: 750rpx; height: 1334rpx;"></canvas>//拍照将 ImageData 对象绘制到此 canvas 上<canvas type="2d" canvas-id="photo-canvas" id="photo-canvas" style="position:absolute;width:720px;height:1280px;top:-9999px;left:-9999px;"></canvas>// js/** —– 鉴权配置 —– *//** * 腾讯云账号 APPID * * 进入[腾讯云账号中心](https://console.cloud.tencent.com/developer) 即可查看 APPID */const APPID = ''; // 此处请填写你自己的参数/** * Web LicenseKey * * 登录音视频终端 SDK 控制台的[Web License 管理](https://console.cloud.tencent.com/vcube/web),创建项目即可获得 LicenseKey */const LICENSE_KEY = ''; // 此处请填写你自己的参数/** * 计算签名用的密钥 Token * * 注意:此处仅用于 DEMO 调试,正式环境中请将 Token 保管在服务端,签名方法迁移到服务端实现,通过接口提供,前端调用拉取签名,参考 * [签名方法](https://cloud.tencent.com/document/product/616/71370#.E7.AD.BE.E5.90.8D.E6.96.B9.E6.B3.95) */const token = ''; // 此处请填写你自己的参数Component({ data: { makeupList: [], stickerList: [], filterList: [], recording: false }, methods: { async getCanvasNode(id) { return new Promise((resolve) => { this.createSelectorQuery() .select(`#${id}`) .node() .exec((res) => { const canvasNode = res[0].node; resolve(canvasNode); }); }); }, getSignature() { const timestamp = Math.round(new Date().getTime() / 1000); const signature = sha256(timestamp + token + APPID + timestamp).toUpperCase(); return { signature, timestamp }; }, // 初始化相机类型 async initSdkCamera() { // 获取在屏的 canvas,sdk 会将处理完的画面实时输出到 canvas 上 const outputCanvas = await this.getCanvasNode("main-canvas"); // 获取鉴权参数 const auth = { licenseKey: LICENSE_KEY, appId: APP_ID, authFunc: this.getSignature }; // 构造SDK初始化参数 const config = { auth, camera: { width:720, height:1280, }, output: outputCanvas, // 初始美颜效果(可选) beautify: { whiten: 0.1, // 美白 0-1 dermabrasion: 0.3, // 磨皮 0-1 lift: 0, // 瘦脸 0-1 shave: 0, // 削脸 0-1 eye: 0.2, // 大眼 0-1 chin: 0, // 下巴 0-1 }, plugin3d, // 需要 3D 素材的场景 }; const ar = new ArSdk(config); // created回调里可以开始获取内置特效与滤镜列表 ar.on('created', () => { // 获取内置美妆、贴纸列表 ar.getEffectList({ Type: 'Preset' }).then((res) => { const list = res.map(item => ({ name: item.Name, id: item.EffectId, cover: item.CoverUrl, url: item.Url, label: item.Label, type: item.PresetType, })); const makeupList = list.filter(item=>item.label.indexOf('美妆')>=0) const stickerList = list.filter(item=>item.label.indexOf('贴纸')>=0) // 渲染特效列表 this.setData({ makeupList, stickerList }); }).catch((e) => { console.log(e); }); // 内置滤镜 ar.getCommonFilter().then((res) => { const list = res.map(item => ({ name: item.Name, id: item.EffectId, cover: item.CoverUrl, url: item.Url, label: item.Label, type: item.PresetType, })); // 渲染滤镜列表 this.setData({ filterList: list }); }).catch((e) => { console.log(e); }); }); // ready 回调中可以设置美颜、滤镜、特效效果 ar.on('ready', (e) => { this._sdkReady = true }); ar.on('error', (e) => { console.log(e); }); this.ar = ar }, // 改变美颜参数,需要确保sdk ready onChangeBeauty(val){ if(!this._sdkReady) return // 可以通过setBeautify设置美颜效果,支持6种属性,详见SDK接入指南 this.ar.setBeautify({ dermabrasion: val.dermabrasion, // 磨皮 0-1 }); }, // 改变美妆,需要确保sdk ready onChangeMakeup(id, intensity){ if(!this._sdkReady) return // 使用setEffect设置特效,setEffect的输入参数支持三种格式,详见SDK接入指南 this.ar.setEffect([{id, intensity}]); }, // 改变贴纸,需要确保sdk ready onChangeSticker(id, intensity){ if(!this._sdkReady) return // 使用setEffect设置特效,setEffect的输入参数支持三种格式,详见SDK接入指南 this.ar.setEffect([{id, intensity}]); }, // 改变滤镜,需要确保sdk ready onChangeFilter(id, intensity){ if(!this._sdkReady) return // 使用setFilter设置滤镜,第二个参数表示滤镜强度(范围0-1) this.ar.setFilter(id, 1); } }})
六、步骤5:拍照和录像功能实现
示例代码如下:
拍照录像SDK 会返回包含宽高和 buffer 数据的对象,用户可以通过自己页面内预设的 2d canvas(上述代码中 id 为 photo-canvas)绘制此数据并导出为图片文件。async takePhoto() { const {uint8ArrayData, width, height} = this.ar.takePhoto(); // takePhoto 方法返回当前画面的 buffer 数据 const photoCanvasNode = await this.getCanvasNode('photo-canvas'); photoCanvasNode.width = parseInt(width); photoCanvasNode.height = parseInt(height); const ctx = photoCanvasNode.getContext('2d'); // 用 sdk 返回的数据创建 ImageData 对象 const imageData = photoCanvasNode.createImageData(uint8ArrayData, width, height); // 将 ImageData 对象绘制到 canvas 上 ctx.putImageData(imageData,0,0,0,0,width,height); // 将 canvas 保存为本地图片 wx.canvasToTempFilePath({ canvas: photoCanvasNode, x: 0, y: 0, width: width, height: height, destWidth: width, destHeight: height, success: (res) => { // 保存照片到本地 wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath }); } })}Component({ methods: { // 开始录像 startRecord() { this.setData({ recording: true }); this.ar.startRecord() } // 结束录像 async stopRecord() { const res = await this.ar.stopRecord(); // 保存录像到本地 wx.saveVideoToPhotosAlbum({ filePath: res.tempFilePath }); this.setData({ recording: false }); } }})当小程序切换后台或检测到手机锁屏时,需要调用 stopRecord 停止录像,再次回到页面时重新开启 SDK 即可。onShow() { this.ar && this.ar.start();},onHide() { this.ar && this.ar.stop();},async onUnload() { try { this.ar && this.ar.stop(); if (this.data.recording) { await this.ar.stopRecord({ destroy: true, }); } } catch (e) { } this.ar && this.ar.destroy();}
七、代码示例
你可以下载 示例代码 解压后查看 ar-miniprogram 代码目录。