直播预览层添加滤镜效果(CIFilter使用场景)

来源:互联网 发布:适合编程的输入法 编辑:程序博客网 时间:2024/06/05 02:38

直播预览层添加滤镜效果

原理,在显示之前,提前对图片进行滤镜处理,把处理后的图片展示出来就好了.

CIFiter(滤镜类):给图片添加特殊效果(模糊,高亮等等).

CIFiter滤镜分类(一个滤镜可能属于多个分类)

kCICategoryDistortionEffect 扭曲效果,比如bump、旋转、hole

kCICategoryGeometryAdjustment 几何开着调整,比如仿射变换、平切、透视转换

kCICategoryCompositeOperation 合并,比如源覆盖(source over)、最小化、源在顶(source atop)、色彩混合模式

kCICategoryHalftoneEffect Halftone效果,比如screen、line screen、hatched

kCICategoryColorAdjustment 色彩调整,比如伽马调整、白点调整、曝光

kCICategoryColorEffect 色彩效果,比如色调调整、posterize

kCICategoryTransition 图像间转换,比如dissolve、disintegrate with mask、swipe

kCICategoryTileEffect 瓦片效果,比如parallelogram、triangle

kCICategoryGenerator 图像生成器,比如stripes、constant color、checkerboard

kCICategoryGradient 渐变,比如轴向渐变、仿射渐变、高斯渐变

kCICategoryStylize 风格化,比如像素化、水晶化

kCICategorySharpen 锐化、发光

kCICategoryBlur 模糊,比如高斯模糊、焦点模糊、运动模糊

kCICategoryStillImage 能用于静态图像

kCICategoryVideo 能用于视频

kCICategoryInterlaced 能用于交错图像

kCICategoryNonSquarePixels 能用于非矩形像素

kCICategoryHighDynamicRange 能用于HDR

kCICategoryBuiltIn 获取所有滤镜

常用图片处理滤镜:

//怀旧-->CIPhotoEffectInstant单色-->CIPhotoEffectMono

//黑白-->CIPhotoEffectNoir褪色-->CIPhotoEffectFade

//色调-->CIPhotoEffectTonal冲印-->CIPhotoEffectProcess

//岁月-->CIPhotoEffectTransfer铬黄-->CIPhotoEffectChrome

自动处理滤镜,通过CIImage获取,CIImage会自动对图片进行滤镜处理

CVImageBufferRef imageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);

// 转换为

CIImageCIImage*ciImage = [CIImageimageWithCVImageBuffer:imageBuffer];

NSArray*fiters = [ciImage autoAdjustmentFilters];

NSLog(@"%@",fiters);

常有的自动滤镜

CIRedEyeCorrection:修复因相机的闪光灯导致的各种红眼CIFaceBalance:调整肤色CIVibrance:在不影响肤色的情况下,改善图像的饱和度CIToneCurve:改善图像的对比度CIHighlightShadowAdjust:改善阴影细节

滤镜对象创建(也可以使用coreImage自动处理滤镜,就不需要自己创建)

滤镜属性可以通过inputKeys属性获取

滤镜工作原理,给滤镜传入一个图片,滤镜有个方法,可以获取处理完成的图片outputImage.

CIFilter *fiter = [CIFilterfilterWithName:@"CIPhotoEffectInstant"]; 

 [fitersetValue:ciImageforKey:@"inputImage"];  ciImage = fiter.outputImage;

直播预览层添加滤镜效果步骤

取出捕获到的帧(CMSampleBufferRef) -> 获取帧里面图片信息(CVImageBufferRef) -> CIFiter滤镜处理 ->转换成UIImage -> 设置为UIImageView的image就能实时显示捕获的画面

if(_videoConnection == connection) {

// 获取图片信息

CVImageBufferRef imageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);

// 转换为

CIImageCIImage*ciImage = [CIImageimageWithCVImageBuffer:imageBuffer];

// 创建滤镜

CIFilter*fiter = [CIFilterfilterWithName:@"CIFaceBalance"];      

  [fiter setValue:ciImage forKey:@"inputImage"];     

   [fiter setValue:@100forKey:@"inputStrength"];       

 ciImage = fiter.outputImage;

// 转换

UIImageUIImage*image = [UIImageimageWithCIImage:ciImage];dispatch_sync(dispatch_get_main_queue(), ^{

self.imageView.image = image;   

     });  

  }

通过GPU渲染图片显示

只有OpenGL才能操控GPU,需要用到OpenGL才行

CIContext:通过这个上下文的方法渲染图片(createCGImage)

CIContext:通过OpenGL的上下文创建,就能用GPU渲染图片,处理图片效率高.(contextWithEAGLContext)

// 获取图片信息

CVImageBufferRef imageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);

// 转换为

CIImageCIImage*ciImage = [CIImageimageWithCVImageBuffer:imageBuffer];

// 创建滤镜CIFilter*fiter = [CIFilterfilterWithName:@"CIPhotoEffectInstant"];      

      [fiter setValue:ciImage forKey:@"inputImage"];         

   ciImage = fiter.outputImage;           

 EAGLContext *openglCtx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

CIContext*ctx = [CIContextcontextWithEAGLContext:openglCtx];

CGImageRefimgRef = [ctx createCGImage:ciImage fromRect:ciImage.extent];

UIImage*image = [UIImageimageWithCGImage:imgRef];

// 用完了及时清空,否则内存溢出,造成程序崩溃.使用C语言的时候,需要特别注意内存管理.CGImageRelease(imgRef);

// 转换UIImagedispatch_sync(dispatch_get_main_queue(), ^{self.imageView.image = image;     

       });

注意点:有个地方需要自己管理内存,否则程序会闪退,报下列错误


内存溢出bug.png

CGImageRefimgRef = [ctx createCGImage:ciImage fromRect:ciImage.extent];UIImage*image = [UIImageimageWithCGImage:imgRef];// 用完了及时清空,否则内存溢出,造成程序崩溃.使用C语言的时候,需要特别注意内存管理.CGImageRelease(imgRef);

注意点:会报坏内存访问,原因有些对象销毁了,没有及时清空,再次用到就坏内存访问

测试:不需要添加滤镜效果,容易测试出来,报下列错误


坏内存访问.png

解决:把一个周期的代码,放入一个自动释放池里管理,下一个运行循环,会自动清空已经销毁的对象。

自动释放池:可以用来管理一段代码中对象的生命周期。

@autoreleasepool{

// 获取图片信息

CVImageBufferRef imageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);

// 转换为CIImageCIImage*ciImage = [CIImageimageWithCVImageBuffer:imageBuffer];

// 创建滤镜CIFilter*fiter = [CIFilterfilterWithName:@"CIPhotoEffectInstant"];      

      [fiter setValue:ciImage forKey:@"inputImage"];           

 ciImage = fiter.outputImage;         

   EAGLContext *openglCtx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

CIContext*ctx = [CIContextcontextWithEAGLContext:openglCtx];

CGImageRefimgRef = [ctx createCGImage:ciImage fromRect:ciImage.extent];

UIImage*image = [UIImageimageWithCGImage:imgRef];

// 用完了及时清空,否则内存溢出,造成程序崩溃.使用C语言的时候,需要特别注意内存管理.CGImageRelease(imgRef);

// 转换UIImagedispatch_sync(dispatch_get_main_queue(), ^{self.imageView.image = image;          

  });    

    } 

   }

原创粉丝点击