使用美颜特效处理图片

本教程指导如何使用美颜特效 SDK 在浏览器中对图片进行美化、应用特效、下载处理完的图片等操作。

准备工作

请阅读 Web 美颜特效 SDK License申请,熟悉 License 申请及使用,准备好 License。
请阅读 Web 美颜特效 SDK 接入指南,熟悉 SDK 的基本用法。

开始使用

步骤1:Web 美颜特效 SDK 引入

创建一个 ar-demo.html 文件,引入下述依赖 js 文件。
<script charset="utf-8" src="https://webar-static.tencent-cloud.com/ar-sdk/resources/latest/webar-sdk.umd.js"></script>
<script src="https://webar-static.tencent-cloud.com/docs/examples/js-sha256/0.9.0/sha256.min.js"></script>
注意:
这里使用 script 标签方式引入,您也可以参考 安装 SDK 中的方法,用 npm 包的方式引入。
webar-sdk.umd.js 为主包,是必须的。
sha256.min.js 是获取 Signature 签名时候用的包,此处仅作为 demo 项目演示用。

步骤2:初始化 Web 美颜特效 SDK

将上述 准备工作 中获取的 APPID、LICENSE_KEY 及 token,填写到下述示例代码中:
<img id="inputImageElement" src="https://webar-static.tencent-cloud.com/docs/test/m4-1080.jpg">
<canvas id="arOutputElement" style="width: 400px;display: inline-block;margin-left: 20px;"></canvas>
/** ----- 鉴权配置 ----- */

/**
* 腾讯云账号 APPID
*
* 进入[腾讯云账号中心](https://console.cloud.tencent.com/developer) 即可查看 APPID
*/
const APPID = ''; // 此处请填写您自己的参数

/**
* Web LicenseKey
*
* 上述准备工作中创建的 license
*/
const LICENSE_KEY = ''; // 此处请填写您自己的参数

/**
* 计算签名用的密钥 Token
*
* 注意:此处仅用于 DEMO 调试,正式环境中请将 Token 保管在服务端,签名方法迁移到服务端实现,通过接口提供,前端调用拉取签名,参考
* 获取签名信息(https://cloud.tencent.com/document/product/616/71364#cf3401f9-e22e-4f54-9e2d-942c08be0f93)
*/
const token = ''; // 此处请填写您自己的参数

/** ----------------------- */

/**
* 定义获取签名方法
*
* 注意:此处方案仅适用于 DEMO 调试,正式环境中签名方法推荐在服务端实现,通过接口提供,前端调用拉取签名,参考
* 准备签名信息(https://cloud.tencent.com/document/product/616/71364#e4ce3483-41f7-4391-83ae-f4b61e221ea0)
*/
const getSignature = function () {
const timestamp = Math.round(new Date().getTime() / 1000);
const signature = sha256(timestamp + token + APPID + timestamp).toUpperCase();
return { signature, timestamp };
};
const inputImageElement = document.getElementById('inputImageElement');
const arOutputElement = document.getElementById('arOutputElement');
// ar sdk 基础配置参数
const config = {
module: {
beautify: true,
},
auth: {
licenseKey: LICENSE_KEY,
appId: APPID,
authFunc: getSignature
},
input: inputImageElement, // 输入图片所在的 imag element
output: arOutputElement, // 输出处理后的图片到指定的 canvas 容器
beautify: { // 默认的美颜配置
"eye": 0.5,
"whiten": 0.4,
"dermabrasion": 0.6,
"lift": 0.1,
"shave": 0.2,
},
}

// config 传入 ar sdk,初始化 ArSdk 实例
const { ArSdk } = window.AR;
const arSdk = new ArSdk(config);
arSdk.on('error', (e) => {
console.log(e);
});

步骤 3:设置输入图片

此处通过 input 标签选择图片文件,调用 updateInputImage 接口更新图片。
<input type="file" id="imageInput" accept="image/*" style="display: none;">
const imageInput = document.getElementById('imageInput');
imageInput.addEventListener('change', function () {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (event) {
inputImageElement.src = event.target.result;
inputImageElement.onload = function () {
arSdk.updateInputImage({
width: inputImageElement.width,
height: inputImageElement.height,
input: inputImageElement,
})
};
};
reader.readAsDataURL(file);
}
});

步骤 4:设置美颜、美妆、贴纸等素材

通过 setBeautify 接口设置美颜,setEffect 接口设置美妆、人脸贴纸等素材。
// 设置美妆
function setMakeUp() {
if (!arSdk) return
arSdk.setEffect([{
id: 'CE82819618A6CDA3', // 美妆,贴纸等素材 id
intensity: 0.8
}])
}
// 清空美妆
function clearMakeUp() {
if (!arSdk) return
arSdk.setEffect(null)
}

// 设置美颜
function setBeautify() {
if (!arSdk) return
arSdk.setBeautify({
"eye": Math.random() * 1,
"whiten": Math.random() * 1,
"dermabrasion": Math.random() * 1,
"lift": Math.random() * 1,
"shave": Math.random() * 1,
})
}
// 清空美颜
function clearBeautify() {
if (!arSdk) return
arSdk.setBeautify({
"eye": 0,
"whiten": 0,
"dermabrasion": 0,
"lift": 0,
"shave": 0,
})
}

步骤 5:下载处理后的图片

通过 takePhoto 接口获取处理后的图片 ImageData,渲染到 canvas 中并下载。
<canvas id="photoCanvas" style="display: none;"></canvas>
<button id="downloadImage">下载图片</button>
const downloadImage = document.getElementById('downloadImage');
downloadImage.addEventListener('click', async () => {
if (!arSdk) {
alert('Please initAR first~')
return
}
const imageData = await arSdk.takePhoto();
photoCanvas.width = imageData.width;
photoCanvas.height = imageData.height;

const context = photoCanvas.getContext("2d");
context.putImageData(imageData, 0, 0);
const base64Image = photoCanvas.toDataURL("image/png");
const a = document.createElement("a");
a.href = base64Image;
a.download = "downloadedImage.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})

步骤6:运行 Demo

启动一个本地 server 服务,访问指定的端口。
此处以 serve 模块 启用为例,在 demo 所在目录执行 serve .
看到以下输出表示本地 server 服务启动成功。
Serving! │
│ │
│ - Local: http://localhost:57965 │
│ - On Your Network: http://10.91.28.94:57965 │
│ │
│ This port was picked because 5000 is in use. │
│ │
│ Copied local address to clipboard!
浏览器访问上述端口,预览效果。
注意:
Demo 依赖浏览器摄像头麦克风权限,请确保访问的页面已授权。
完整的代码片段如下,运行前请补全代码中的 APPID、 LICENSE_KEY、及 token 相关信息:
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Upload and Display</title>
</head>

<body>
<div>
step1: <button id="initAR">初始化 AR SDK</button>
</br>
step2: <button id="selectAndProcess">更新图片</button>
</div>
<div>
step3: <button onclick="setMakeUp()">设置特效</button>
<button onclick="clearMakeUp()">清空特效</button>
<button onclick="setBeautify()">设置美颜</button>
<button onclick="clearBeautify()">清空美颜</button>
</div>
<div>
step4: <button id="downloadImage">下载图片</button>
</div>
<input type="file" id="imageInput" accept="image/*" style="display: none;">
<br>
<img id="inputImageElement" src="https://webar-static.tencent-cloud.com/docs/test/m4-1080.jpg">
<canvas id="arOutputElement" style="display: inline-block;"></canvas>
<canvas id="photoCanvas" style="display: none;"></canvas>
<script charset="utf-8" src="https://webar-static.tencent-cloud.com/ar-sdk/resources/latest/webar-sdk.umd.js">
</script>
<script src="https://webar-static.tencent-cloud.com/docs/examples/js-sha256/0.9.0/sha256.min.js"></script>
<script>
let arSdk;
// todo:Enter the license information
const APPID = "";
const LICENSE_KEY = "";
const token = "";
const getSignature = function () {
const timestamp = Math.round(new Date().getTime() / 1000);
const signature = sha256(timestamp + token + APPID + timestamp).toUpperCase();
return {
signature,
timestamp
};
};
const selectAndProcess = document.getElementById('selectAndProcess');
const imageInput = document.getElementById('imageInput');
const downloadImage = document.getElementById('downloadImage');
const inputImageElement = document.getElementById('inputImageElement');
const initArBtn = document.getElementById('initAR');
const arOutputElement = document.getElementById('arOutputElement');
const photoCanvas = document.getElementById('photoCanvas');
initArBtn.addEventListener('click', async () => {
arSdk = await getInstance();
alert('Init AR SDK Success!!!')
})
selectAndProcess.addEventListener('click', () => {
if (!arSdk) {
alert('Please click initAR to init AR SDK')
return
}
imageInput.click();
})
downloadImage.addEventListener('click', async () => {
if (!arSdk) {
alert('Please click initAR to init AR SDK')
return
}
const imageData = await arSdk.takePhoto();
photoCanvas.width = imageData.width;
photoCanvas.height = imageData.height;

const context = photoCanvas.getContext("2d");
context.putImageData(imageData, 0, 0);
const base64Image = photoCanvas.toDataURL("image/png");
const a = document.createElement("a");
a.href = base64Image;
a.download = "downloadedImage.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
imageInput.addEventListener('change', function () {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (event) {
inputImageElement.src = event.target.result;
inputImageElement.onload = function () {
arSdk.updateInputImage({
width: inputImageElement.width,
height: inputImageElement.height,
input: inputImageElement,
})
};

};
reader.readAsDataURL(file);
}
});

function setMakeUp() {
if (!arSdk) return
arSdk.setEffect([{
id: 'CE82819618A6CDA3', // 美妆,贴纸等素材 id
intensity: 0.8
}])
}

function clearMakeUp() {
if (!arSdk) return
arSdk.setEffect(null)
}

function clearBeautify() {
if (!arSdk) return
arSdk.setBeautify({
"eye": 0,
"whiten": 0,
"dermabrasion": 0,
"lift": 0,
"shave": 0,
})
}

function setBeautify() {
if (!arSdk) return
arSdk.setBeautify({
"eye": Math.random() * 1,
"whiten": Math.random() * 1,
"dermabrasion": Math.random() * 1,
"lift": Math.random() * 1,
"shave": Math.random() * 1,
})
}
async function getInstance() {
if (arSdk) {
return Promise.resolve(arSdk)
}
const config = {
module: {
beautify: true,
segmentation: false
},
auth: {
licenseKey: LICENSE_KEY,
appId: APPID,
authFunc: getSignature
},
input: inputImageElement,
output: arOutputElement,
beautify: {
"eye": Math.random() * 1,
"whiten": Math.random() * 1,
"dermabrasion": Math.random() * 1,
"lift": Math.random() * 1,
"shave": Math.random() * 1,
},
}
return new Promise((resolve) => {
const sdk = new window.AR.ArSdk(config)
sdk.on('resourceReady', async () => {
// get makeuplist
sdk.getEffectList({
Type: 'Preset',
Label: 'Makeup',
}).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,
}));
console.log('makeuplist', list)
})
resolve(sdk)
})
sdk.on('ready', () => {

})
sdk.on('error', (e) => {
console.log(e);
});
})
}
</script>

</body>

</html>