Facebetter Beauty Engine 使用说明
目录
快速开始
Facebetter Beauty Engine 是一个跨平台的美颜效果引擎,支持基础美颜、面部重塑、美妆效果和虚拟背景等功能。
基本使用流程
cpp
// 1. 配置日志(调试和监控)
facebetter::LogConfig log_config;
log_config.console_enabled = true;
facebetter::BeautyEffectEngine::SetLogConfig(log_config);
// 2. 创建引擎
facebetter::EngineConfig config;
config.app_id = "your_app_id";
config.app_key = "your_app_key";
config.resource_path = "path/to/resource.bundle";
auto engine = facebetter::BeautyEffectEngine::Create(config);
// 3. 创建图像数据
auto image_frame = facebetter::ImageFrame::CreateWithFile("input.jpg");
// 4. 设置处理模式
engine->SetProcessMode(facebetter::ProcessMode::Video);
// 5. 配置美颜效果
engine->SetBeautyTypeEnabled(facebetter::BeautyType::Basic, true);
engine->SetBeautyParam(facebetter::beauty_params::Basic::Smoothing, 0.5f);
// 6. 处理图像
auto result = engine->ProcessImage(image_frame);
// 7. 获取结果
auto rgba_buffer = result->ToRGBA();日志配置
重要提示:日志配置应该在创建引擎之前进行,这样可以在引擎初始化过程中看到详细的日志信息。
日志配置结构
cpp
struct LogConfig {
bool console_enabled = false; // 是否输出到控制台
bool file_enabled = false; // 是否输出到文件
LogLevel level = LogLevel::Info; // 日志级别
std::string file_name = ""; // 日志文件名
};日志级别
cpp
enum class LogLevel {
Trace = 0, // 跟踪级别
Debug, // 调试级别
Info, // 信息级别
Warn, // 警告级别
Error, // 错误级别
Critical // 严重错误级别
};配置示例
cpp
// 配置日志输出到控制台和文件
facebetter::LogConfig log_config;
log_config.console_enabled = true;
log_config.file_enabled = true;
log_config.level = facebetter::LogLevel::Info;
log_config.file_name = "beauty_engine.log";
int result = facebetter::BeautyEffectEngine::SetLogConfig(log_config);
if (result != 0) {
std::cerr << "Failed to set log config" << std::endl;
}引擎初始化
引擎配置 (EngineConfig)
引擎创建需要提供以下配置信息:
cpp
struct EngineConfig {
std::string app_id; // 应用ID
std::string app_key; // 应用密钥
std::string resource_path; // 资源文件路径
ProcessMode process_mode; // 处理模式(默认Video)
};创建引擎实例
cpp
// 静态方法创建引擎
auto engine = facebetter::BeautyEffectEngine::Create(config);
if (!engine) {
// 创建失败处理
std::cerr << "Failed to create BeautyEffectEngine" << std::endl;
}引擎生命周期管理
引擎使用智能指针管理,无需手动释放:
cpp
// 引擎会自动在作用域结束时释放
std::shared_ptr<facebetter::BeautyEffectEngine> engine =
facebetter::BeautyEffectEngine::Create(config);图像数据管理
重要提示:在设置处理模式之前,建议先了解您要处理的图像数据格式和来源,这样可以更好地选择合适的处理模式。
1. 从文件创建
cpp
auto image_frame = facebetter::ImageFrame::CreateWithFile("path/to/image.jpg");2. 从内存数据创建
cpp
// 通用创建方法(推荐)
auto image_frame = facebetter::ImageFrame::Create(
data, width, height, facebetter::ImageBuffer::Format::RGBA);
// 特定格式创建方法
// RGBA 格式
auto rgba_frame = facebetter::ImageFrame::CreateWithRGBA(
rgba_data, width, height, stride);
// BGRA 格式
auto bgra_frame = facebetter::ImageFrame::CreateWithBGRA(
bgra_data, width, height, stride);
// RGB 格式
auto rgb_frame = facebetter::ImageFrame::CreateWithRGB(
rgb_data, width, height, stride);
// BGR 格式
auto bgr_frame = facebetter::ImageFrame::CreateWithBGR(
bgr_data, width, height, stride);3. YUV 格式创建
cpp
// I420 格式
auto i420_frame = facebetter::ImageFrame::CreateWithI420(
width, height, y_data, stride_y, u_data, stride_u, v_data, stride_v);
// NV12 格式
auto nv12_frame = facebetter::ImageFrame::CreateWithNV12(
width, height, y_data, stride_y, uv_data, stride_uv);
// NV21 格式
auto nv21_frame = facebetter::ImageFrame::CreateWithNV21(
width, height, y_data, stride_y, vu_data, stride_vu);4. Android Camera2 相机数据
cpp
auto android_frame = facebetter::ImageFrame::CreateWithAndroid420(
width, height, y_buffer, stride_y, u_buffer, stride_u,
v_buffer, stride_v, pixel_stride_uv);图像格式转换
ImageFrame 支持多种格式之间的转换,返回的是对应的 ImageBuffer 对象:
cpp
// 转换为 RGBA
auto rgba_buffer = image_frame->ToRGBA();
// 转换为 BGRA
auto bgra_buffer = image_frame->ToBGRA();
// 转换为 RGB
auto rgb_buffer = image_frame->ToRGB();
// 转换为 BGR
auto bgr_buffer = image_frame->ToBGR();
// 转换为 YUV 格式
auto i420_buffer = image_frame->ToI420();
auto nv12_buffer = image_frame->ToNV12();
auto nv21_buffer = image_frame->ToNV21();图像旋转
cpp
// 旋转图像
int result = image_frame->Rotate(facebetter::ImageBuffer::Rotation::Rotate90);ImageBuffer 详解
重要提示:ImageFrame 内部使用 ImageBuffer 存储图像数据。当您调用
ToRGBA()等方法时,返回的是 ImageBuffer 对象,它提供了直接访问图像数据的能力。
ImageBuffer 与 ImageFrame 的关系
cpp
// ImageFrame 是高级封装,ImageBuffer 是底层数据存储
auto image_frame = facebetter::ImageFrame::CreateWithFile("input.jpg");
// 获取底层的 ImageBuffer 对象
auto rgba_buffer = image_frame->ToRGBA(); // 返回 RGBAImageBuffer*
// ImageBuffer 提供直接的数据访问
const uint8_t* data = rgba_buffer->Data();
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
int stride = rgba_buffer->Stride();支持的图像格式
cpp
enum class Format {
I420, // YUV 4:2:0 12bpp (3 planes: Y, U, V)
NV12, // YUV 4:2:0 12bpp (2 planes: Y + UV)
NV21, // YUV 4:2:0 12bpp (2 planes: Y + VU, Android 默认)
BGRA, // BGRA 8:8:8:8 32bpp (4 channels)
RGBA, // RGBA 8:8:8:8 32bpp (4 channels)
BGR, // BGR 8:8:8 24bpp (3 channels)
RGB, // RGB 8:8:8 24bpp (3 channels)
Texture, // 纹理格式(用于 GPU 纹理)
};访问图像数据
cpp
auto rgba_buffer = image_frame->ToRGBA();
// 获取图像基本信息
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
int stride = rgba_buffer->Stride();
int size = rgba_buffer->Size();
ImageBuffer::Format format = rgba_buffer->GetFormat();
// 获取图像数据指针
const uint8_t* data = rgba_buffer->Data();
// 对于 YUV 格式的特殊访问方法
auto i420_buffer = image_frame->ToI420();
const uint8_t* y_data = i420_buffer->DataY();
const uint8_t* u_data = i420_buffer->DataU();
const uint8_t* v_data = i420_buffer->DataV();
int stride_y = i420_buffer->StrideY();
int stride_u = i420_buffer->StrideU();
int stride_v = i420_buffer->StrideV();实际应用示例
cpp
// 从文件加载图像
auto image_frame = facebetter::ImageFrame::CreateWithFile("input.jpg");
// 转换为 RGBA 格式进行处理
auto rgba_buffer = image_frame->ToRGBA();
if (rgba_buffer) {
// 获取图像数据用于显示或保存
const uint8_t* data = rgba_buffer->Data();
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
// 可以用于 OpenGL 纹理、文件保存等
SaveImageToFile(data, width, height, "output.png");
// 或者用于显示
DisplayImage(data, width, height);
}内存管理注意事项
cpp
// ImageBuffer 使用智能指针管理,自动释放内存
auto rgba_buffer = image_frame->ToRGBA();
// ImageBuffer 提供只读数据访问
const uint8_t* data = rgba_buffer->Data();
// 注意:ImageBuffer 是只读的,不能直接修改数据
// data[0] = 255; // 错误!ImageBuffer 是只读的
// 如果需要修改数据,应该:
// 1. 创建新的 ImageFrame
// 2. 或者使用其他图像处理库进行修改处理模式设置
重要提示:根据您的应用场景选择合适的处理模式。图像模式适合单张图片处理,视频模式适合实时视频流处理。
处理模式类型
cpp
enum class ProcessMode {
Image = 0, // 图像模式 - 适合单张图片处理
Video = 1 // 视频模式 - 适合实时视频流处理
};设置处理模式
cpp
// 设置为图像模式
engine->SetProcessMode(facebetter::ProcessMode::Image);
// 设置为视频模式
engine->SetProcessMode(facebetter::ProcessMode::Video);
// 获取当前处理模式
auto current_mode = engine->ProcessMode();设置渲染视图
平台限制:
SetRenderView方法目前仅在 iOS 和 macOS 平台可用。
cpp
// 设置渲染视图(仅 iOS/macOS 平台支持)
// 在 iOS 上,view 是 UIView*
// 在 macOS 上,view 是 NSView*
#if defined(FB_PLATFORM_IOS) || defined(FB_PLATFORM_MAC)
int result = engine->SetRenderView(view_handle);
// 检查设置结果
if (result == 0) {
std::cout << "Render view set successfully" << std::endl;
} else {
std::cerr << "Failed to set render view, error code: " << result << std::endl;
}
#endif返回值说明
大部分方法返回 int 类型,表示操作结果:
0:操作成功- 非
0:操作失败,具体错误码请参考错误码定义
模式选择建议
图像模式 (Image):
- 单张图片美颜处理
- 批量图片处理
- 对处理质量要求较高的场景
视频模式 (Video):
- 实时摄像头美颜
- 视频流处理
- 对处理速度要求较高的场景
美颜效果配置
美颜类型
cpp
enum class BeautyType {
Basic = 0, // 基础美颜
Reshape, // 面部重塑
Makeup, // 美妆效果
VirtualBackground, // 虚拟背景
};启用/禁用美颜类型
cpp
// 启用基础美颜
engine->SetBeautyTypeEnabled(facebetter::BeautyType::Basic, true);
// 禁用面部重塑
engine->SetBeautyTypeEnabled(facebetter::BeautyType::Reshape, false);
// 禁用所有美颜效果
engine->DisableAllBeautyTypes();
// 检查美颜类型是否启用
bool is_basic_enabled = engine->IsBeautyTypeEnabled(facebetter::BeautyType::Basic);基础美颜参数
cpp
enum class Basic {
Smoothing = 0, // 磨皮 (0.0 - 1.0)
Sharpening, // 锐化 (0.0 - 1.0)
Whitening, // 美白 (0.0 - 1.0)
Rosiness, // 红润 (0.0 - 1.0)
};
// 设置磨皮强度
engine->SetBeautyParam(facebetter::beauty_params::Basic::Smoothing, 0.5f);
// 设置美白强度
engine->SetBeautyParam(facebetter::beauty_params::Basic::Whitening, 0.3f);面部重塑参数
cpp
enum class Reshape {
FaceThin = 0, // 瘦脸 (0.0 - 1.0)
FaceVShape, // V脸 (0.0 - 1.0)
FaceNarrow, // 窄脸 (0.0 - 1.0)
FaceShort, // 短脸 (0.0 - 1.0)
Cheekbone, // 颧骨 (0.0 - 1.0)
Jawbone, // 下颌骨 (0.0 - 1.0)
Chin, // 下巴 (0.0 - 1.0)
NoseSlim, // 瘦鼻梁 (0.0 - 1.0)
EyeSize, // 大眼 (0.0 - 1.0)
EyeDistance, // 眼距 (0.0 - 1.0)
};
// 设置瘦脸强度
engine->SetBeautyParam(facebetter::beauty_params::Reshape::FaceThin, 0.4f);
// 设置大眼强度
engine->SetBeautyParam(facebetter::beauty_params::Reshape::EyeSize, 0.6f);美妆参数
cpp
enum class Makeup {
Lipstick, // 口红 (0.0 - 1.0)
Blush, // 腮红 (0.0 - 1.0)
};
// 设置口红强度
engine->SetBeautyParam(facebetter::beauty_params::Makeup::Lipstick, 0.7f);
// 设置腮红强度
engine->SetBeautyParam(facebetter::beauty_params::Makeup::Blush, 0.5f);虚拟背景
cpp
// 设置虚拟背景
facebetter::beauty_params::VirtualBackgroundOptions options;
options.mode = facebetter::beauty_params::BackgroundMode::Blur; // 模糊背景
engine->SetVirtualBackground(options);
// 设置背景图片(需要先设置为 Image 模式)
facebetter::beauty_params::VirtualBackgroundOptions imageOptions;
imageOptions.mode = facebetter::beauty_params::BackgroundMode::Image;
imageOptions.background_image = backgroundImageFrame; // ImageFrame 对象
engine->SetVirtualBackground(imageOptions);图像处理流程
基本处理流程
cpp
// 1. 准备输入图像
auto input_frame = facebetter::ImageFrame::CreateWithFile("input.jpg");
// 2. 处理图像
auto processed_frame = engine->ProcessImage(input_frame);
// 3. 检查处理结果
if (processed_frame) {
// 4. 获取处理后的 ImageBuffer 数据
auto rgba_buffer = processed_frame->ToRGBA();
if (rgba_buffer) {
// 5. 使用处理后的数据
const uint8_t* data = rgba_buffer->Data();
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
// 例如:保存到文件、显示到屏幕等
SaveImageToFile(data, width, height, "output.png");
}
}ProcessImage 与 ImageBuffer 的关系
重要提示:
ProcessImage返回的ImageFrame包含处理后的ImageBuffer数据。您需要调用相应的转换方法来获取特定格式的ImageBuffer。
获取处理结果的不同方式
cpp
auto processed_frame = engine->ProcessImage(input_frame);
if (processed_frame) {
// 方式1:获取 RGBA 格式数据(最常用)
auto rgba_buffer = processed_frame->ToRGBA();
if (rgba_buffer) {
const uint8_t* data = rgba_buffer->Data();
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
// 用于显示、保存等
}
// 方式2:获取 BGRA 格式数据
auto bgra_buffer = processed_frame->ToBGRA();
// 方式3:获取 RGB 格式数据(无透明通道)
auto rgb_buffer = processed_frame->ToRGB();
// 方式4:获取 YUV 格式数据(适合视频处理)
auto i420_buffer = processed_frame->ToI420();
auto nv12_buffer = processed_frame->ToNV12();
}处理结果的实际应用
cpp
auto processed_frame = engine->ProcessImage(input_frame);
if (processed_frame) {
auto rgba_buffer = processed_frame->ToRGBA();
if (rgba_buffer) {
// 应用1:用于 OpenGL 渲染
const uint8_t* data = rgba_buffer->Data();
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
int stride = rgba_buffer->Stride();
// 上传到 OpenGL 纹理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);
// 应用2:用于网络传输
std::vector<uint8_t> image_data(data, data + rgba_buffer->Size());
SendImageOverNetwork(image_data);
// 应用3:用于显示
DisplayImage(data, width, height);
// 应用4:保存到文件(需要使用其他图像库)
SaveImageToFile(data, width, height, "processed_image.png");
}
}实时处理示例
cpp
// 视频流处理循环
while (has_more_frames) {
// 获取新帧
auto new_frame = GetNextFrame();
// 处理帧
auto processed_frame = engine->ProcessImage(new_frame);
if (processed_frame) {
// 获取处理后的数据
auto rgba_buffer = processed_frame->ToRGBA();
if (rgba_buffer) {
// 显示处理结果
DisplayFrame(rgba_buffer->Data(),
rgba_buffer->Width(),
rgba_buffer->Height());
}
}
}性能优化建议
cpp
// 优化1:选择合适的输出格式
void OptimizedProcessing() {
auto processed_frame = engine->ProcessImage(input_frame);
// 如果只需要显示,使用 RGBA
auto rgba_buffer = processed_frame->ToRGBA();
// 如果用于视频编码,使用 I420
auto i420_buffer = processed_frame->ToI420();
// 如果用于某些显示系统,使用 BGRA
auto bgra_buffer = processed_frame->ToBGRA();
}
// 优化2:避免频繁的格式转换
void EfficientProcessing() {
auto processed_frame = engine->ProcessImage(input_frame);
// 根据最终用途选择格式,避免多次转换
if (need_for_display) {
auto rgba_buffer = processed_frame->ToRGBA();
DisplayImage(rgba_buffer->Data(), rgba_buffer->Width(), rgba_buffer->Height());
} else if (need_for_video_encoding) {
auto i420_buffer = processed_frame->ToI420();
EncodeVideoFrame(i420_buffer);
}
}完整示例
基础美颜示例
cpp
#include "facebetter/beauty_effect_engine.h"
#include "facebetter/image_frame.h"
int main() {
// 1. 配置日志(第一步:调试和监控)
facebetter::LogConfig log_config;
log_config.console_enabled = true;
log_config.file_enabled = true;
log_config.level = facebetter::LogLevel::Info;
log_config.file_name = "beauty_engine.log";
facebetter::BeautyEffectEngine::SetLogConfig(log_config);
// 2. 创建引擎(第二步:初始化)
facebetter::EngineConfig config;
config.app_id = "demo_app";
config.app_key = "demo_key";
config.resource_path = "resource/resource.bundle";
config.process_mode = facebetter::ProcessMode::Video;
auto engine = facebetter::BeautyEffectEngine::Create(config);
if (!engine) {
std::cerr << "Failed to create engine" << std::endl;
return -1;
}
// 3. 创建图像数据(第三步:准备数据)
auto input_frame = facebetter::ImageFrame::CreateWithFile("input.jpg");
if (!input_frame) {
std::cerr << "Failed to load input image" << std::endl;
return -1;
}
// 4. 设置处理模式(第四步:根据场景选择模式)
engine->SetProcessMode(facebetter::ProcessMode::Image); // 单张图片处理
// 可选:设置渲染视图(仅 iOS/macOS 平台支持)
// #if defined(FB_PLATFORM_IOS) || defined(FB_PLATFORM_MAC)
// engine->SetRenderView(view_handle);
// #endif
// 5. 配置美颜效果(第五步:设置效果参数)
engine->SetBeautyTypeEnabled(facebetter::BeautyType::Basic, true);
engine->SetBeautyTypeEnabled(facebetter::BeautyType::Reshape, true);
// 设置基础美颜参数
engine->SetBeautyParam(facebetter::beauty_params::Basic::Smoothing, 0.5f);
engine->SetBeautyParam(facebetter::beauty_params::Basic::Whitening, 0.3f);
// 设置面部重塑参数
engine->SetBeautyParam(facebetter::beauty_params::Reshape::FaceThin, 0.4f);
engine->SetBeautyParam(facebetter::beauty_params::Reshape::EyeSize, 0.6f);
// 6. 处理图像(第六步:执行处理)
auto result = engine->ProcessImage(input_frame);
if (result) {
// 7. 获取结果(第七步:获取处理后的 ImageBuffer 数据)
auto rgba_buffer = result->ToRGBA();
if (rgba_buffer) {
std::cout << "Processing completed successfully" << std::endl;
std::cout << "Output size: " << rgba_buffer->Width()
<< "x" << rgba_buffer->Height() << std::endl;
// 获取图像数据
const uint8_t* data = rgba_buffer->Data();
int width = rgba_buffer->Width();
int height = rgba_buffer->Height();
int stride = rgba_buffer->Stride();
// 保存到文件(需要使用其他图像库,如 OpenCV、stb_image 等)
SaveImageToFile(data, width, height, "output.png");
std::cout << "Image saved to output.png" << std::endl;
// 或者用于其他用途(显示、网络传输等)
// DisplayImage(data, width, height);
// SendImageOverNetwork(data, width, height, stride);
}
} else {
std::cerr << "Failed to process image" << std::endl;
return -1;
}
return 0;
}实时视频处理示例
cpp
#include "facebetter/beauty_effect_engine.h"
#include "facebetter/image_frame.h"
int main() {
// 1. 配置日志
facebetter::LogConfig log_config;
log_config.console_enabled = true;
log_config.level = facebetter::LogLevel::Warn; // 减少日志输出
facebetter::BeautyEffectEngine::SetLogConfig(log_config);
// 2. 创建引擎
facebetter::EngineConfig config;
config.app_id = "video_app";
config.app_key = "video_key";
config.resource_path = "resource/resource.bundle";
config.process_mode = facebetter::ProcessMode::Video;
auto engine = facebetter::BeautyEffectEngine::Create(config);
if (!engine) {
std::cerr << "Failed to create engine" << std::endl;
return -1;
}
// 3. 设置处理模式为视频模式
engine->SetProcessMode(facebetter::ProcessMode::Video);
// 4. 设置渲染视图(仅 iOS/macOS 平台支持)
// #if defined(FB_PLATFORM_IOS) || defined(FB_PLATFORM_MAC)
// engine->SetRenderView(view_handle);
// #endif
// 5. 配置美颜效果
engine->SetBeautyTypeEnabled(facebetter::BeautyType::Basic, true);
engine->SetBeautyParam(facebetter::beauty_params::Basic::Smoothing, 0.3f);
engine->SetBeautyParam(facebetter::beauty_params::Basic::Whitening, 0.2f);
// 6. 视频处理循环
while (has_more_frames) {
// 获取新帧(从摄像头或视频文件)
auto new_frame = GetNextFrame();
if (!new_frame) {
break;
}
// 处理帧
auto processed_frame = engine->ProcessImage(new_frame);
if (processed_frame) {
// 获取处理后的 ImageBuffer 数据
auto rgba_buffer = processed_frame->ToRGBA();
if (rgba_buffer) {
// 显示处理结果
DisplayFrame(rgba_buffer->Data(),
rgba_buffer->Width(),
rgba_buffer->Height());
// 或者保存关键帧
if (should_save_frame) {
std::string filename = "frame_" + std::to_string(frame_count) + ".png";
SaveImageToFile(rgba_buffer->Data(),
rgba_buffer->Width(),
rgba_buffer->Height(),
filename);
}
}
}
}
return 0;
}常见问题
Q: 引擎创建失败怎么办?
A: 检查以下几点:
- 确认
app_id和app_key正确 - 确认
resource_path路径存在且可访问 - 检查日志输出获取详细错误信息
Q: 图像处理失败怎么办?
A: 检查以下几点:
- 确认输入图像格式支持
- 检查图像数据是否有效
- 确认已启用相应的美颜类型
Q: 如何优化性能?
A: 建议:
- 使用视频模式进行实时处理
- 合理设置美颜参数强度
- 避免频繁创建和销毁 ImageFrame
Q: 支持哪些图像格式?
A: 支持常见格式:
- 输入:JPG, PNG, BMP 等文件格式
- 内存:RGBA, BGRA, RGB, BGR, I420, NV12, NV21
- 输出:所有输入格式均可转换
Q: 如何处理大尺寸图像?
A: 建议:
- 根据实际需求调整图像尺寸
- 使用合适的处理模式
- 监控内存使用情况
Q: ImageBuffer 和 ImageFrame 有什么区别?
A: 区别如下:
- ImageFrame:高级封装类,提供便捷的创建和转换方法
- ImageBuffer:底层数据存储类,提供直接的数据访问接口
- 使用场景:ImageFrame 用于日常使用,ImageBuffer 用于需要直接操作数据的场景
Q: ImageBuffer 内存管理有什么注意事项?
A: 重要注意事项:
- 使用智能指针自动管理内存
- ImageBuffer 是只读的,不能直接修改数据
- 如果需要修改数据,应该创建新的 ImageFrame 或使用其他图像处理库
- 避免频繁的格式转换
Q: 如何优化 ImageBuffer 的性能?
A: 优化建议:
- 根据最终用途选择合适的输出格式
- 避免频繁的格式转换
- 合理使用 ImageBuffer 对象
- 根据应用场景选择合适的图像格式
Q: SetRenderView 方法如何使用?
A: SetRenderView 用于设置渲染目标视图:
- 用途:实时预览美颜效果
- 平台限制:目前仅在 iOS 和 macOS 平台可用
- 参数类型:iOS 使用 UIView*,macOS 使用 NSView*
- 返回值:0 表示成功,非 0 表示失败
- 使用场景:主要用于实时摄像头美颜预览
Q: 如何选择合适的图像格式?
A: 根据应用场景选择:
- RGBA:通用格式,适合显示和保存
- I420:YUV 格式,适合视频处理,文件较小
- NV12/NV21:Android 相机常用格式
- RGB/BGR:无透明通道,适合某些显示场景
- Texture:GPU 纹理格式,适合 OpenGL 渲染