tencent cloud

文档反馈

美颜特效小程序拍摄实践

最后更新时间:2023-11-06 15:37:27

    准备工作

    小程序开发入门请参见 微信小程序文档
    请阅读 Web 美颜特效 SDK 接入指南,熟悉 SDK 基本用法。

    开始使用

    步骤1:小程序后台配置域名白名单

    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. 安装:
    npm install tencentcloud-webar
    2. 构建: 打开小程序开发者工具,顶部菜单选择 工具 > 构建 npm
    3. 在 app.json 中配置 workers 路径:
    "workers": "miniprogram_npm/tencentcloud-webar/worker"

    步骤3:引入文件

    // 0.3.0之前版本引用方式(1个文件)
    // import "../../miniprogram_npm/tencentcloud-webar/lib.js";
    // 0.3.0及之后版本引用方式(2个文件 + 按需初始化3d模块)
    import '../../miniprogram_npm/tencentcloud-webar/lib.js';
    import '../../miniprogram_npm/tencentcloud-webar/core.js';
    // 按需初始化3d插件,如果不需要3d则可以不引用
    import '../../miniprogram_npm/tencentcloud-webar/lib-3d.js';
    import { plugin3d } from '../../miniprogram_npm/tencentcloud-webar/plugin-3d'
    // 导入 ArSdk
    import { ArSdk } from "../../miniprogram_npm/tencentcloud-webar/index.js";
    注意
    小程序有单文件不超过 500kb 的限制,因此 SDK 分为两个 js 文件提供。
    0.3.0版本之后,对 SDK 进行了进一步的拆分,新增3D支持,针对3D模块提供按需加载方式,导入前请确认当前使用的 SDK 版本信息,选择对应的导入方式。

    步骤4:初始化 SDK

    注意
    小程序初始化 SDK 前须在控制台配置小程序 APPID,请参见 快速上手
    需在页面中插入 camera 标签来打开相机,然后设置 camera 参数,参数配置详情请参见 接入指南
    小程序不支持 getOutput,需要自行传入一个在屏的 webgl canvas,SDK 直接输出画面到此 canvas 上。
    示例代码如下:
    // 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
    }
    };
    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 代码目录。
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持