WebRTC音視頻通話-實現GPUImage視頻美顏濾鏡效果iOS

WebRTC音視頻通話-實現GPUImage視頻美顏濾鏡效果

在WebRTC音視頻通話的GPUImage美顏效果圖如下

在這里插入圖片描述

可以看下
之前搭建ossrs服務,可以查看:https://blog.csdn.net/gloryFlow/article/details/132257196
之前實現iOS端調用ossrs音視頻通話,可以查看:https://blog.csdn.net/gloryFlow/article/details/132262724
之前WebRTC音視頻通話高分辨率不顯示畫面問題,可以查看:https://blog.csdn.net/gloryFlow/article/details/132262724
修改SDP中的碼率Bitrate,可以查看:https://blog.csdn.net/gloryFlow/article/details/132263021

一、GPUImage是什么?

GPUImage是iOS上一個基于OpenGL進行圖像處理的開源框架,內置大量濾鏡,架構靈活,可以在其基礎上很輕松地實現各種圖像處理功能。

GPUImage中包含各種濾鏡,這里我不會使用那么多,使用的是GPUImageLookupFilter及GPUImagePicture

GPUImage中有一個專門針對lookup table進行處理的濾鏡函數GPUImageLookupFilter,使用這個函數就可以直接對圖片進行濾鏡添加操作了。代碼如下

/**GPUImage中有一個專門針對lookup table進行處理的濾鏡函數GPUImageLookupFilter,使用這個函數就可以直接對圖片進行濾鏡添加操作了。originalImg是你希望添加濾鏡的原始圖片@param image 原圖@return 處理后的圖片*/
+ (UIImage *)applyLookupFilter:(UIImage *)image lookUpImage:(UIImage *)lookUpImage {if (lookUpImage == nil) {return image;}UIImage *inputImage = image;UIImage *outputImage = nil;GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];//添加濾鏡GPUImageLookupFilter *lookUpFilter = [[GPUImageLookupFilter alloc] init];//導入之前保存的NewLookupTable.png文件GPUImagePicture *lookupImg = [[GPUImagePicture alloc] initWithImage:lookUpImage];[lookupImg addTarget:lookUpFilter atTextureLocation:1];[stillImageSource addTarget:lookUpFilter atTextureLocation:0];[lookUpFilter useNextFrameForImageCapture];if([lookupImg processImageWithCompletionHandler:nil] && [stillImageSource processImageWithCompletionHandler:nil]) {outputImage= [lookUpFilter imageFromCurrentFramebuffer];}return outputImage;
}

這個需要lookUpImage,圖列表如下

在這里插入圖片描述

由于暫時沒有整理demo的git

這里在使用applyLomofiFilter再試下效果

SDApplyFilter.m中的幾個方法

+ (UIImage *)applyBeautyFilter:(UIImage *)image {GPUImageBeautifyFilter *filter = [[GPUImageBeautifyFilter alloc] init];[filter forceProcessingAtSize:image.size];GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];[pic addTarget:filter];[pic processImage];[filter useNextFrameForImageCapture];return [filter imageFromCurrentFramebuffer];
}/**Amatorka濾鏡 Rise濾鏡,可以使人像皮膚得到很好的調整@param image image@return 處理后的圖片*/
+ (UIImage *)applyAmatorkaFilter:(UIImage *)image
{GPUImageAmatorkaFilter *filter = [[GPUImageAmatorkaFilter alloc] init];[filter forceProcessingAtSize:image.size];GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];[pic addTarget:filter];[pic processImage];[filter useNextFrameForImageCapture];return [filter imageFromCurrentFramebuffer];
}/**復古型濾鏡,感覺像舊上海灘@param image image@return 處理后的圖片*/
+ (UIImage *)applySoftEleganceFilter:(UIImage *)image
{GPUImageSoftEleganceFilter *filter = [[GPUImageSoftEleganceFilter alloc] init];[filter forceProcessingAtSize:image.size];GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];[pic addTarget:filter];[pic processImage];[filter useNextFrameForImageCapture];return [filter imageFromCurrentFramebuffer];
}/**圖像黑白化,并有大量噪點@param image 原圖@return 處理后的圖片*/
+ (UIImage *)applyLocalBinaryPatternFilter:(UIImage *)image
{GPUImageLocalBinaryPatternFilter *filter = [[GPUImageLocalBinaryPatternFilter alloc] init];[filter forceProcessingAtSize:image.size];GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];[pic addTarget:filter];[pic processImage];[filter useNextFrameForImageCapture];return [filter imageFromCurrentFramebuffer];
}/**單色濾鏡@param image 原圖@return 處理后的圖片*/
+ (UIImage *)applyMonochromeFilter:(UIImage *)image
{GPUImageMonochromeFilter *filter = [[GPUImageMonochromeFilter alloc] init];[filter forceProcessingAtSize:image.size];GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];[pic addTarget:filter];[pic processImage];[filter useNextFrameForImageCapture];return [filter imageFromCurrentFramebuffer];
}

使用GPUImageSoftEleganceFilter復古型濾鏡,感覺像舊上海灘效果圖如下
在這里插入圖片描述

使用GPUImageLocalBinaryPatternFilter圖像黑白化效果圖如下

在這里插入圖片描述

使用GPUImageMonochromeFilter 效果圖如下

在這里插入圖片描述

二、WebRTC實現音視頻通話中視頻濾鏡處理

之前實現iOS端調用ossrs音視頻通話,可以查看:https://blog.csdn.net/gloryFlow/article/details/132262724
這個已經有完整的代碼了,這里暫時做一下調整。

為RTCCameraVideoCapturer的delegate指向代理

- (RTCVideoTrack *)createVideoTrack {RTCVideoSource *videoSource = [self.factory videoSource];self.localVideoSource = videoSource;// 如果是模擬器if (TARGET_IPHONE_SIMULATOR) {if (@available(iOS 10, *)) {self.videoCapturer = [[RTCFileVideoCapturer alloc] initWithDelegate:self];} else {// Fallback on earlier versions}} else{self.videoCapturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:self];}RTCVideoTrack *videoTrack = [self.factory videoTrackWithSource:videoSource trackId:@"video0"];return videoTrack;
}

實現RTCVideoCapturerDelegate的方法didCaptureVideoFrame

#pragma mark - RTCVideoCapturerDelegate處理代理
- (void)capturer:(RTCVideoCapturer *)capturer didCaptureVideoFrame:(RTCVideoFrame *)frame {
//    DebugLog(@"capturer:%@ didCaptureVideoFrame:%@", capturer, frame);// 調用SDWebRTCBufferFliter的濾鏡處理RTCVideoFrame *aFilterVideoFrame;if (self.delegate && [self.delegate respondsToSelector:@selector(webRTCClient:didCaptureVideoFrame:)]) {aFilterVideoFrame = [self.delegate webRTCClient:self didCaptureVideoFrame:frame];}//  操作C 需要手動釋放  否則內存暴漲
//      CVPixelBufferRelease(_buffer)//    拿到pixelBuffer
//        ((RTCCVPixelBuffer*)frame.buffer).pixelBufferif (!aFilterVideoFrame) {aFilterVideoFrame = frame;}[self.localVideoSource capturer:capturer didCaptureVideoFrame:frame];
}

之后調用SDWebRTCBufferFliter,實現濾鏡效果。
實現將((RTCCVPixelBuffer *)frame.buffer).pixelBuffer進行渲染,這里用到了EAGLContext、CIContext

EAGLContext是OpenGL繪制句柄或者上下文,在繪制試圖之前,需要指定使用創建的上下文繪制。
CIContext是用來渲染CIImage,將作用在CIImage上的濾鏡鏈應用到原始的圖片數據中。我這里需要將UIImage轉換成CIImage。

具體代碼實現如下

SDWebRTCBufferFliter.h

#import <Foundation/Foundation.h>
#import "WebRTCClient.h"@interface SDWebRTCBufferFliter : NSObject- (RTCVideoFrame *)webRTCClient:(WebRTCClient *)client didCaptureVideoFrame:(RTCVideoFrame *)frame;@end

SDWebRTCBufferFliter.m

#import "SDWebRTCBufferFliter.h"
#import <VideoToolbox/VideoToolbox.h>
#import "SDApplyFilter.h"@interface SDWebRTCBufferFliter ()
// 濾鏡
@property (nonatomic, strong) EAGLContext *eaglContext;@property (nonatomic, strong) CIContext *coreImageContext;@property (nonatomic, strong) UIImage *lookUpImage;@end@implementation SDWebRTCBufferFliter- (instancetype)init
{self = [super init];if (self) {self.eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];self.coreImageContext = [CIContext contextWithEAGLContext:self.eaglContext options:nil];self.lookUpImage = [UIImage imageNamed:@"lookup_jiari"];}return self;
}- (RTCVideoFrame *)webRTCClient:(WebRTCClient *)client didCaptureVideoFrame:(RTCVideoFrame *)frame {CVPixelBufferRef pixelBufferRef = ((RTCCVPixelBuffer *)frame.buffer).pixelBuffer;//    CFRetain(pixelBufferRef);if (pixelBufferRef) {CIImage *inputImage = [CIImage imageWithCVPixelBuffer:pixelBufferRef];CGImageRef imgRef = [_coreImageContext createCGImage:inputImage fromRect:[inputImage extent]];UIImage *fromImage = nil;if (!fromImage) {fromImage = [UIImage imageWithCGImage:imgRef];}UIImage *toImage;toImage = [SDApplyFilter applyMonochromeFilter:fromImage];
//
//        if (toImage == nil) {
//            toImage = [SDApplyFilter applyLookupFilter:fromImage lookUpImage:self.lookUpImage];
//        } else {
//            toImage = [SDApplyFilter applyLookupFilter:fromImage lookUpImage:self.lookUpImage];
//        }if (toImage == nil) {toImage = fromImage;}CGImageRef toImgRef = toImage.CGImage;CIImage *ciimage = [CIImage imageWithCGImage:toImgRef];[_coreImageContext render:ciimage toCVPixelBuffer:pixelBufferRef];CGImageRelease(imgRef);//必須釋放fromImage = nil;toImage = nil;ciimage = nil;inputImage = nil;}RTCCVPixelBuffer *rtcPixelBuffer =[[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixelBufferRef];RTCVideoFrame *filteredFrame =[[RTCVideoFrame alloc] initWithBuffer:rtcPixelBufferrotation:frame.rotationtimeStampNs:frame.timeStampNs];return filteredFrame;
}@end

至此可以看到在WebRTC音視頻通話中GPUImage視頻美顏濾鏡的具體效果了。

三、小結

WebRTC音視頻通話-實現GPUImage視頻美顏濾鏡效果。主要用到GPUImage處理視頻畫面CVPixelBufferRef,將處理后的CVPixelBufferRef生成RTCVideoFrame,通過調用localVideoSource中實現的didCaptureVideoFrame方法。內容較多,描述可能不準確,請見諒。

本文地址:https://blog.csdn.net/gloryFlow/article/details/132265842

學習記錄,每天不停進步。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40026.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40026.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40026.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2023秋招筆試

檸檬微趣 將java的鏈表升序排序&#xff0c;鏈表用Class Node{int val,Node next}實現 import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner;/*** 輸入一串數字&#xff0c;放入list中&#xff0c;實現sortList&#xff0c;返回升序的li…

將單個訓練數據集文件拆分為:image文件和label文件(pytorch學習+螞蟻蜜蜂數據集)

螞蟻蜜蜂分類數據集下載鏈接&#xff1a;https://download.pytorch.org/tutorial/hymenoptera_data.zip 要實現如圖操作&#xff1a; 將ants分為ants_image和ants_label 將bees分成bees_image和bees_label 創建ants_label和bees_label&#xff0c;并且以圖片名作為txt文件的…

Apche Kafka + Spring的消息監聽容器

目錄 一、消息的接收1.1、消息監聽器 二、消息監聽容器2.1、 實現方法2.1.1、KafkaMessageListenerContainer2.1.1.1、 基本概念2.1.1.2、如何使用 KafkaMessageListenerContainer 2.1.2、ConcurrentMessageListenerContainer 三、偏移 四、監聽器容器自動啟動 一、消息的接收 …

【機器學習】sklearn數據集的使用,數據集的獲取和劃分

「作者主頁」&#xff1a;士別三日wyx 「作者簡介」&#xff1a;CSDN top100、阿里云博客專家、華為云享專家、網絡安全領域優質創作者 「推薦專欄」&#xff1a;對網絡安全感興趣的小伙伴可以關注專欄《網絡安全入門到精通》 sklearn數據集 二、安裝sklearn二、獲取數據集三、…

mac錄屏工具,錄屏沒有聲音的解決辦法

mac錄屏工具&#xff0c;錄屏沒有聲音的解決辦法 在使用macbook錄制屏幕時&#xff0c;發現自帶的錄屏工具QuickTime Player沒有聲音&#xff0c;于是嘗試了多款錄屏工具&#xff0c;對其做一些經驗總結&#xff08;省流&#xff1a;APP Store直接可以免費下載使用Omi錄屏專家…

第三課-界面介紹SD-Stable Diffusion 教程

前言 我們已經安裝好了SD&#xff0c;這篇文章不介紹難以理解的原理&#xff0c;說使用。以后再介紹原理。 我的想法是&#xff0c;先學會畫&#xff0c;然后明白原理&#xff0c;再去提高技術。 我失敗過&#xff0c;知道三天打魚兩天曬網的痛苦&#xff0c;和很多人一樣試了…

TiDB數據庫從入門到精通系列之六:使用 TiCDC 將 TiDB 的數據同步到 Apache Kafka

TiDB數據庫從入門到精通系列之六&#xff1a;使用 TiCDC 將 TiDB 的數據同步到 Apache Kafka 一、技術流程二、搭建環境三、創建Kafka changefeed四、寫入數據以產生變更日志五、配置 Flink 消費 Kafka 數據 一、技術流程 快速搭建 TiCDC 集群、Kafka 集群和 Flink 集群創建 c…

【網絡編程系列】網絡編程實戰

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kuan 的首頁,持續學…

使用Vue.js框架的指令和事件綁定實現一個購物車的頁面布局

使用了v-model指令來實現全選/全不選的功能&#xff0c;當全選框被點擊時&#xff0c;isAllChecked的值會被改變。使用了v-if指令來判斷購物車中是否有商品&#xff0c;如果有商品則渲染商品列表&#xff0c;否則顯示購物車為空的提示。使用了v-for指令來遍歷datalist數組&…

jvm內存溢出排查(使用idea自帶的內存泄漏分析工具)

文章目錄 1.確保生成內存溢出文件2.使用idea自帶的內存泄漏分析工具3.具體實驗一下 1.確保生成內存溢出文件 想分析堆內存溢出&#xff0c;一定在運行jar包時就寫上參數-XX:HeapDumpOnOutOfMemoryError&#xff0c;可以看我之前關于如何運行jar包的文章。若你沒有寫。可以寫上…

Keepalived入門指南:實現故障轉移和負載均衡

文章目錄 一、簡介1. Keepalived概述2. 高可用性和負載均衡的重要性 二、故障轉移1. 什么是故障轉移2. Keepalived的故障轉移原理a) VRRP協議b) 虛擬路由器ID和優先級 3. 配置Keepalived實現故障轉移a) 主備服務器的設置b) 監控網絡接口c) 虛擬IP的配置d) 備份服務器接管流程 三…

Python學習筆記_基礎篇(九)_面向對象編程

本篇內容: 1、反射2、面向對象編程3、面向對象三大特性4、類成員5、類成員修飾符6、類的特殊成員7、單例模式 反射 python中的反射功能是由以下四個內置函數提供&#xff1a;hasattr、getattr、setattr、delattr&#xff0c;改四個函數分別用于對對象內部執行&#xff1a;檢…

el-form自定義校驗規則

Vue 的 el-form 組件可以使用自定義校驗規則進行表單驗證。自定義校驗規則可以通過傳遞一個函數來實現&#xff0c;該函數接受要校驗的字段的值作為參數&#xff0c;并返回一個布爾值或一個 Promise 對象。 下面是一個示例&#xff0c;演示如何在 el-form 中使用自定義校驗規則…

若依前端npm run dev啟動時報錯

本文主要解決問題:若依前端npm run dev啟動時報錯,解決辦法。 目錄 1、第1種解決方案(親測有效) 2、第2種解決方案(親測有效) Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:67:19)at Object.createHash (node…

解決 adb install 錯誤INSTALL_FAILED_UPDATE_INCOMPATIBLE

最近給游戲出包&#xff0c;平臺要求 v1 簽名吧&#xff0c;AS 打包后&#xff0c;adb 執行安裝到手機&#xff0c;我用的設備是google pixel6 , android 系統 13&#xff0c; 提示如下&#xff1a; adb install -r v5_android_202308161046.apk Performing Streamed Install a…

centos 安裝.net 6 sdk

按照以下步驟在 CentOS 上安裝 .NET 6 SDK&#xff1a; 更新系統&#xff1a; sudo yum update安裝依賴項&#xff1a; sudo yum install -y curl libunwind libicu下載并添加 Microsoft 的軟件包存儲庫密鑰&#xff1a; sudo rpm -Uvh https://packages.microsoft.com/config/…

單片機第一季:零基礎13——AD和DA轉換

1&#xff0c;AD轉換基本概念 51 單片機系統內部運算時用的全部是數字量&#xff0c;即0 和1&#xff0c;因此對單片機系統而言&#xff0c;無法直接操作模擬量&#xff0c;必須將模擬量轉換成數字量。所謂數字量&#xff0c;就是用一系列0 和1 組成的二進制代碼表示某個信號大…

Linux -- 進階 Autofs自動掛載服務 實驗詳解

服務端創建共享目錄&#xff0c; 客戶端實現自動掛載 第一步 &#xff1a; 客戶端&#xff0c;服務端 均關閉安全軟件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootnode1 ~]# setenforce 0 [rootnode1 ~]# systemctl stop firewalld 第二…

在K8s上處理nginx

基本說明 創建一個名為ssl的TLS類型的Secret對象&#xff0c;用于存儲證書和密鑰信息。 kubectl create secret tls ssl --certserver.crt --keyserver.key配置Nginx的events塊&#xff0c;設置worker連接數為1024。 events {worker_connections 1024; }配置Nginx的http塊&a…

MyBaits(單獨使用,與整合無關)小白版

文章目錄 概述比較配置寫xml加載上面配置并執行加載配置的方法方式一 執行方法方式一方式二(MyBatis映射器) 寫配置文件的映射文件設置對象的別名&#xff08;簡寫&#xff09;獲取自動生成的主鍵 查詢結果和java的映射規則基本類型映射&#xff1a;簡單對象映射&#xff1a;嵌…