Skip to content

实现 Web 美颜

集成 SDK

通过 npm 安装:

bash
npm install facebetter

使用 ES Module(推荐):

javascript
import { 
  BeautyEffectEngine, 
  EngineConfig, 
  BeautyType, 
  BasicParam,
  ReshapeParam,
  MakeupParam,
  BackgroundMode,
  VirtualBackgroundOptions,
  ProcessMode 
} from 'facebetter';

使用 CommonJS:

javascript
const { BeautyEffectEngine, EngineConfig } = require('facebetter');

日志配置

默认日志是关闭的,可以按需开启:

javascript
await engine.setLogConfig({
    consoleEnabled: true,  // 控制台日志
    fileEnabled: false,    // 文件日志(浏览器环境不支持)
    level: 0,              // 日志级别:0=DEBUG, 1=INFO, 2=WARN, 3=ERROR
    fileName: 'facebetter.log'  // 日志文件名(可选,仅当 fileEnabled 为 true 时有效)
});

注意:日志配置需要在引擎初始化之前调用。

创建配置引擎

按照 此页面 指引,获取 appIdappKey

javascript
import { BeautyEffectEngine, EngineConfig } from 'facebetter';

const config = new EngineConfig({
    appId: 'your appId',     // 配置你的 appid
    appKey: 'your appKey'    // 配置你的 appkey
});
const engine = new BeautyEffectEngine(config);

错误处理

创建引擎后建议检查是否成功:

javascript
try {
    await engine.init();
    console.log('引擎初始化成功');
} catch (error) {
    console.error('引擎初始化失败:', error);
    // 处理错误
}

启用特效类型

美颜功能可以按类型开启关闭,根据订阅版本启用相应的美颜类型,每种类型还有对应的参数可以调节

javascript
import { BeautyType } from 'facebetter';

// 所有订阅版本都支持
engine.setBeautyTypeEnabled(BeautyType.Basic, true);
// Pro, Pro+ 版本支持
engine.setBeautyTypeEnabled(BeautyType.Reshape, true);
// Pro, Pro+ 版本支持
engine.setBeautyTypeEnabled(BeautyType.Makeup, true);
// 仅 Pro+ 版本支持
engine.setBeautyTypeEnabled(BeautyType.VirtualBackground, true);

检查操作结果

所有 API 调用都应该检查返回值或使用 try-catch:

javascript
import { BeautyType } from 'facebetter';

try {
    engine.setBeautyTypeEnabled(BeautyType.Basic, true);
    console.log('成功启用基础美颜');
} catch (error) {
    console.error('启用基础美颜失败:', error);
}

调节美颜参数

设置美肤参数

通过 setBasicParam 接口,设置美肤参数,参数范围 [0.0, 1.0](浮点数);

javascript
import { BasicParam } from 'facebetter';

engine.setBasicParam(
    BasicParam.Smoothing, 
    0.5  // 0.0-1.0
);

支持的美肤参数:

javascript
BasicParam = {
    Smoothing: 0,   // 磨皮
    Sharpening: 1,  // 锐化
    Whitening: 2,   // 美白
    Rosiness: 3     // 红润
};

设置美型参数

通过 setReshapeParam 接口,设置美型参数,参数范围 [0.0, 1.0](浮点数);

javascript
import { ReshapeParam } from 'facebetter';

engine.setReshapeParam(
    ReshapeParam.FaceThin, 
    0.5  // 0.0-1.0
);

支持的美型参数:

javascript
ReshapeParam = {
    FaceThin: 0,      // 瘦脸
    FaceVShape: 1,    // V脸
    FaceNarrow: 2,    // 窄脸
    FaceShort: 3,     // 短脸
    Cheekbone: 4,     // 颧骨
    Jawbone: 5,       // 下颌骨
    Chin: 6,          // 下巴
    NoseSlim: 7,      // 瘦鼻梁
    EyeSize: 8,       // 大眼
    EyeDistance: 9    // 眼距
};

设置美妆参数

通过 setMakeupParam 接口,设置美妆参数,参数范围 [0.0, 1.0](浮点数);

javascript
import { MakeupParam } from 'facebetter';

engine.setMakeupParam(
    MakeupParam.Lipstick, 
    0.5  // 0.0-1.0
);

支持的美妆参数:

javascript
MakeupParam = {
    Lipstick: 0,  // 口红
    Blush: 1      // 腮红
};

设置虚拟背景

通过 setBeautyTypeEnabled 接口启用虚拟背景:

javascript
engine.setBeautyTypeEnabled(BeautyType.VirtualBackground, true);

通过 setVirtualBackground 接口设置虚拟背景(统一接口,与其他平台一致):

javascript
import { VirtualBackgroundOptions, BackgroundMode } from 'facebetter';

// 设置模糊背景
const blurOptions = new VirtualBackgroundOptions({
  mode: BackgroundMode.Blur
});
engine.setVirtualBackground(blurOptions);

// 设置图片背景
const bgImage = new Image();
bgImage.onload = () => {
  const imageOptions = new VirtualBackgroundOptions({
    mode: BackgroundMode.Image,
    backgroundImage: bgImage
  });
  engine.setVirtualBackground(imageOptions);
};
bgImage.src = 'background.jpg';

// 关闭虚拟背景
const noneOptions = new VirtualBackgroundOptions({
  mode: BackgroundMode.None
});
engine.setVirtualBackground(noneOptions);

简化写法(也支持):

javascript
// 直接传对象,不需要 new VirtualBackgroundOptions
engine.setVirtualBackground({
  mode: BackgroundMode.Blur
});

// 设置图片背景
bgImage.onload = () => {
  engine.setVirtualBackground({
    mode: BackgroundMode.Image,
    backgroundImage: bgImage
  });
};

处理图像

从 Canvas 获取图像数据

javascript
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

从图片元素获取图像数据

javascript
const img = new Image();
img.onload = function() {
    const canvas = document.createElement('canvas');
    canvas.width = img.width;
    canvas.height = img.height;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0);
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    // 处理图像...
};
img.src = 'image.jpg';

处理图像

processImage 方法支持多种输入类型,processMode 包括 Video 和 Image 两种,Video 适合直播、视频等场景使用,效率更高,Image 模式适合图片处理场景。

javascript
import { ProcessMode } from 'facebetter';

// 方式一:传入 ImageData 和尺寸
const result = engine.processImage(
    imageData, 
    canvas.width, 
    canvas.height, 
    ProcessMode.Video  // 或 ProcessMode.Image
);

// 方式二:传入 HTMLImageElement(自动获取尺寸,width/height 可省略)
const result = engine.processImage(
    imageElement, 
    undefined, 
    undefined, 
    ProcessMode.Image
);

// 方式三:传入 HTMLVideoElement(自动获取尺寸,width/height 可省略)
const result = engine.processImage(
    videoElement, 
    undefined, 
    undefined, 
    ProcessMode.Video
);

// 方式四:传入 Uint8ClampedArray(必须提供 width/height)
const result = engine.processImage(
    uint8Array, 
    640,  // 必需
    480,  // 必需
    ProcessMode.Video
);

绘制处理后图像

javascript
// 将处理后的图像数据绘制到 Canvas
ctx.putImageData(result, 0, 0);

保存处理后的图片

处理后的图像数据可以保存为图片文件:

方式一:使用 Canvas.toDataURL()

javascript
// 将处理后的图像数据绘制到 Canvas
ctx.putImageData(result, 0, 0);

// 转换为 Data URL
const dataURL = canvas.toDataURL('image/png');

// 创建下载链接
const link = document.createElement('a');
link.download = 'beauty-result.png';
link.href = dataURL;
link.click();

方式二:使用 Canvas.toBlob()

javascript
// 将处理后的图像数据绘制到 Canvas
ctx.putImageData(result, 0, 0);

// 转换为 Blob
canvas.toBlob(function(blob) {
    // 创建下载链接
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.download = 'beauty-result.png';
    link.href = url;
    link.click();
    
    // 释放 URL 对象
    URL.revokeObjectURL(url);
}, 'image/png');

方式三:保存为不同格式

javascript
// 保存为 PNG(无损,文件较大)
const pngDataURL = canvas.toDataURL('image/png');

// 保存为 JPEG(有损,文件较小,可设置质量)
const jpegDataURL = canvas.toDataURL('image/jpeg', 0.9); // 质量 0-1

// 创建下载
function downloadImage(dataURL, filename, mimeType) {
    const link = document.createElement('a');
    link.download = filename;
    link.href = dataURL;
    link.click();
}

// 使用
downloadImage(pngDataURL, 'beauty-result.png', 'image/png');
downloadImage(jpegDataURL, 'beauty-result.jpg', 'image/jpeg');

完整示例:保存处理后的图片

javascript
function processAndSaveImage(imageData, engine) {
    try {
        // 处理图像(同步方法)
        const result = engine.processImage(
            imageData, 
            imageData.width, 
            imageData.height, 
            ProcessMode.Image
        );
        
        // 创建临时 Canvas
        const canvas = document.createElement('canvas');
        canvas.width = imageData.width;
        canvas.height = imageData.height;
        const ctx = canvas.getContext('2d');
        
        // 绘制处理后的图像
        ctx.putImageData(result, 0, 0);
        
        // 保存为图片
        canvas.toBlob(function(blob) {
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.download = `beauty-${Date.now()}.png`;
            link.href = url;
            link.click();
            URL.revokeObjectURL(url);
        }, 'image/png');
        
        console.log('图片保存成功');
    } catch (error) {
        console.error('处理或保存图片失败:', error);
    }
}

生命周期管理

释放资源

在页面卸载或不再使用时,务必释放引擎资源:

javascript
// 页面卸载时
window.addEventListener('beforeunload', () => {
    if (engine) {
        engine.destroy();
        engine = null;
    }
});

// 或在组件销毁时(Vue/React)
onUnmounted(() => {  // Vue
    if (engine) {
        engine.destroy();
        engine = null;
    }
});

useEffect(() => {  // React
    return () => {
        if (engine) {
            engine.destroy();
            engine = null;
        }
    };
}, []);

内存管理

  • 及时释放不再使用的 ImageData 对象
  • 避免在循环中重复创建大量图像对象
  • 建议复用 Canvas 和 ImageData 对象
javascript
// 复用 Canvas 和 ImageData
let canvas = null;
let imageData = null;

function processFrame() {
    if (!canvas) {
        canvas = document.createElement('canvas');
        canvas.width = 640;
        canvas.height = 480;
    }
    
    const ctx = canvas.getContext('2d');
    // 绘制图像到 canvas
    ctx.drawImage(video, 0, 0);
    
    // 获取图像数据
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    
    // 处理图像
    const result = engine.processImage(
        imageData, 
        canvas.width, 
        canvas.height, 
        ProcessMode.Video
    );
    
    // 绘制结果
    ctx.putImageData(result, 0, 0);
}

相关文档