上一篇我们实现了拍照功能。接下来我们可以加上贴纸功能。贴纸不是简单的加一个Image View(不然这篇文章没什么好写了~),我们需要把加在摄像头上的贴纸在录像或拍照的时候一起加到帧画面上。
-
在.h文件中添加这次要用到的三个成员变量
UIImage *_overlayImage; CGRect _overlayRect; CGColorSpaceRef _colorSpace;
-
在.m文件viewDidLoad中最后一行之后加上:
_colorSpace = CGColorSpaceCreateDeviceRGB(); // 7. Setup overlay image _overlayImage = [UIImage imageNamed:@"image"]; _overlayRect = CGRectMake(-_overlayImage.size.width / 2.f, -_overlayImage.size.height / 2.f, _overlayImage.size.width, _overlayImage.size.height);
不要忘记找一张图拖入工程中。
_colorSpace的作用在willOutputSampleBuffer:的最后会用到。
-
_colorSpace需要手动释放,把释放动作放在dealloc方法中:
- (void)dealloc { CGColorSpaceRelease(_colorSpace); }
-
到willOutputSampleBuffer:中,先把上次的第一段代码注释掉,不然在不进行拍照的情况下,这个方法走不下去。
-
到第三段代码上方,
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
之前的一行中插入以下代码:// draw overlay image CGContextRotateCTM(context, M_PI_2); CGContextTranslateCTM(context, _sourceRect.size.height / 2.f, -_sourceRect.size.width / 2.f); CGContextDrawImage(context, _overlayRect, _overlayImage.CGImage);
作用是把画布调整一下坐标系,然后把贴图画上去。
-
到了最关键的步骤了。做完对帧画面的一系列处理以后,要写回image buffer里面。我们可以用CIContext的渲染方法来实现。到
willOutputSampleBuffer:
最后一行代码
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
的上方插入以下代码:CIImage *filteredImage = [[CIImage alloc] initWithCGImage:resultImage.CGImage]; [_ciContext render:filteredImage toCVPixelBuffer:imageBuffer bounds:_sourceRect colorSpace:_colorSpace];
这里要注意初始化CIImage的时候不能直接用UIImage,会返回空值。至于为什么……我也不明白。不过既然可以用CGImage初始化,也没有什么大问题了。
-
看下效果吧。(这个贴图是在吐槽的是某国人名字又长又没有规律。)
【iOS开发】制作一个简易的滤镜相机(四)
好了,又一个主要功能点完成。下回再见。
网友评论