这个项目是也有参考了很多开源项目,借鉴了他们的架构和数据处理流程。将有用的功能做了缝合,基于 C++ 开发,性能是非常强的💪🏻,比 GPUimage 还要好一丢丢, 并且支持安卓, iOS 和 Mac 。Win 端和鸿蒙未来也计划支持一下。
调用非常简单,Readme 中有示例,很容为直播和视频通信场景添加美颜和滤镜效果。 个人的第一个做的比较认真的项目,库稳定性和效果已经大量用户(万级别)验证,用到的朋友可以尝试一下,希望大家多多支持,给个 Star👏😬
👉项目地址:https://github.com/pixpark/gpupixel
GPUPixel 是一个高性能的图像和视频处理库,用 C++11 编写。非常容易编译和集成,库的大小非常小。
它基于 GPU ,并且内置了可以达到商业级效果的美颜效果滤镜。
它支持包括 iOS 、Mac 、Android 在内的各种平台,并且理论上可以移植到任何支持 OpenGL/ES 的平台。
当前人脸关键点检测使用了 Face++ 库,但将来将会用 VNN 替代。
美白 & 磨皮:
This table compares the features supported by GPUPixel and GPUImage:
✅: 支持
❌: 不支持
✏️: 计划中
GPUPixel | GPUImage | |
---|---|---|
Filters: | ✅ | ❌ |
磨皮 | ✅ | ❌ |
美白 | ✅ | ❌ |
瘦脸 | ✅ | ❌ |
大眼 | ✅ | ❌ |
口红 | ✅ | ❌ |
腮红 | ✅ | ❌ |
自定义滤镜 | ✅ | ✅ |
输入格式: | ||
YUV420P(I420) | ✅ | ❌ |
RGBA | ✅ | ✅ |
JPEG | ✅ | ✅ |
PNG | ✅ | ✅ |
NV21(for Android) | ✏️ | ❌ |
输出格式: | ||
RGBA | ✅ | ✅ |
YUV420P(I420) | ✏️ | ❌ |
系统支持: | ||
iOS | ✅ | ✅ |
Mac | ✅ | ✅ |
Android | ✅ | ❌ |
Win | ✏️ | ❌ |
Linux | ❌ | ❌ |
OS | iOS | OSX | Android | Windows | Linux |
---|---|---|---|---|---|
Min Support OS Version | 10.0 | 10.13 | 5.0 (API 21) | - | - |
- | iPhone 6P | iPhone 8 | iPhone X | iPhone 11 | iPhone 14 pro |
---|---|---|---|---|---|
CPU | 5% | 5% | 3% | 3% | 3% |
Time Taken | 10ms | 4ms | 3ms | 3ms | 3ms |
- | Xiaomi 10 | Huawei Meta30 | Vivo | SAMSUNG | Google Pixel |
---|---|---|---|---|---|
CPU | 3% | 5% | - | - | - |
Time Taken | 6ms | 5ms | - | - | - |
Open objc/gpupixel.xcodeproj
or objc/demo/PixDemo.xcodeproj
Xcode project and select the corresponding platform for compilation
Open the directory ./android in Android Studio and configure NDK r21+
iOS(.framework) | MacOS(.framework) | Android(.aar) | |
---|---|---|---|
Size | 2.4 MB | 2.6 MB | 2.1 MB |
Refer to ./objc/demo
or ./android
demo
.h
file
// video data input
std::shared_ptr<SourceRawDataInput> source_raw_input_;
// beauty filter
std::shared_ptr<FaceBeautyFilter> face_beauty_filter_;
// video data output
std::shared_ptr<TargetRawDataOutput> target_raw_output_;
Create Filter, .c++
file
GPUPixel::GPUPixelContext::getInstance()->runSync([&] {
// Create filter
source_raw_input_ = SourceRawDataInput::create();
target_raw_output_ = TargetRawDataOutput::create();
// Face Beauty Filter
face_beauty_filter_ = FaceBeautyFilter::create();
// Add filter
source_raw_input_->addTarget(face_beauty_filter_)->addTarget(target_raw_output_);
}
Input Image Data I420 or RGBA
// ...
// YUVI420
source_raw_input_->uploadBytes(width,
height,
bufferY,
strideY,
bufferU,
strideU,
bufferV,
strideV);
// ...
// bytes: RGBA data
source_raw_input_->uploadBytes(bytes,
width,
height,
stride);
Output Data Callback
// I420 callback
target_raw_output_->setI420Callbck([=](const uint8_t *data,
int width,
int height,
int64_t ts) {
size_t y_size = width * height;
const uint8_t *uData = data + y_size;
const uint8_t *vData = data + y_size + y_size / 4;
// Do something you want
});
// RGBA callback->
target_raw_output_->setPixelsCallbck([=](const uint8_t *data,
int width,
int height,
int64_t ts) {
size_t rgba_size = width * height*4;
// Do something you want
});
// Output data callbck
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.