iOS 录屏添加自定义水印

本文介绍了如何在iOS系统录屏功能的基础上,利用RPBroadcastSampleHandler和AVAssetWriter结合CIImage进行视频帧水印的实时添加,包括初始化方法、处理SampleBuffer以及水印渲染到视频帧的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iOS实现系统录屏 RPBroadcastSampleHandler 和 AVAssetWriter 结合使用便可实现,这两个类如何使用这里不做过多说明,文章内容是在已实现录屏功能的情况下如何为视频帧添加水印。

1、初始化方法里添加

#import <Metal/Metal.h>

- (instancetype)init{
    if(self = [super init]){

    //其它代码.......

       
    UIImage *image = [[UIImage alloc] initWithContentsOfFile:@"水印图片路径"];
    _watermarkImage = [CIImage imageWithCGImage:image.CGImage];
   
    id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
    CIContext *ciContext = [CIContext contextWithMTLDevice:metalDevice];
    _ciContext = ciContext;
}
    return self;
}

核心代码:

- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType{

    if(sampleBufferType == RPSampleBufferTypeVideo){
        AVAssetWriterStatus status = self.assetWriter.status;
        if (status == AVAssetWriterStatusFailed || status == AVAssetWriterStatusCompleted || status == AVAssetWriterStatusCancelled) {
            return;
        }
        if (status == AVAssetWriterStatusUnknown) {
            //初始化起始时间
            [self.assetWriter startWriting];
            CMTime time = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
            [self.assetWriter startSessionAtSourceTime:time];
            [self.videoInput appendSampleBuffer:[self addPortraitWatermarkWithBufferRef:sampleBuffer watermark:self.watermarkImage]];
        }
        if(status == AVAssetWriterStatusWriting && self.videoInput.isReadyForMoreMediaData){
            //添加水印处理
            [self.videoInput appendSampleBuffer:[self addPortraitWatermarkWithBufferRef:sampleBuffer watermark:self.watermarkImage]];
        }
    }

}


//水印渲染到视频帧
- (CMSampleBufferRef)addPortraitWatermarkWithBufferRef:(CMSampleBufferRef)sampleBufferRef
                                             watermark:(CIImage *)watermark{
    //核心代码如下:可以按照自己的需求调整水印位置,当前的水印是和屏幕比例相同的图片,并且图片是除了水印部分,其它为透明的图片,所以只需放缩到和视频帧画面大小即可
    CVPixelBufferRef curPixelBuffer = CMSampleBufferGetImageBuffer(sampleBufferRef);
    CVPixelBufferLockBaseAddress(curPixelBuffer, 0);
    CGFloat rrwidth = CVPixelBufferGetWidth(curPixelBuffer);
    CIImage *contentImage = [CIImage imageWithCVPixelBuffer:curPixelBuffer];
    CGFloat rate = rrwidth / contentImage.extent.size.width;
    contentImage = [contentImage imageByApplyingTransform:CGAffineTransformMakeScale(rate, rate)];
    CGFloat imageWidth = watermark.extent.size.width;
    CGFloat w_rate = rrwidth/imageWidth;
    CIImage *tempImage = [watermark imageByApplyingTransform:CGAffineTransformMakeScale(w_rate, w_rate)];
    tempImage = [tempImage imageByCompositingOverImage:contentImage];
    [_ciContext render:tempImage toCVPixelBuffer:curPixelBuffer];
    CVPixelBufferUnlockBaseAddress(curPixelBuffer, 0);
    return sampleBufferRef;
}
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值