重要经验八---UIImage转换为CVPixelBufferRef

来源:互联网 发布:阿卡索 51talk 知乎 编辑:程序博客网 时间:2024/06/13 05:01

照片时间,是我个人开发的一款显示照片拍摄时间的应用,实用、免费、体积小。
http://itunes.apple.com/app/id571238224

最近做一个视频处理的项目(Rokk!),需要将opengl渲染后的特效保存为视频,由于使用了第三方库,所以不能直接使用opengl的framebuffer,后面使用了一种比较蛋疼的方式:使用glReadPixels来读取每一个渲染帧,转换为UIImage,然后将UIImage转换为CVPixelBufferRef,使用AVAssetWriterInputPixelBufferAdaptor和AVAssetWriter保存CVPixelBufferRef,最后生成视频。【此处应该有很多改进空间,希望能够多多交流】。
在上述过程中,遇到了很多坑,其中就包含“UIImage转换为CVPixelBufferRef”,网上有蛮多关于这方面的代码的,但是真正没有什么bug的,太少了,综合了各家的代码,最终我得到了相对比较正确、简洁的代码:
- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image{

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:                         [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,                         [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,                         nil];CVPixelBufferRef pxbuffer = NULL;CGFloat frameWidth = CGImageGetWidth(image);CGFloat frameHeight = CGImageGetHeight(image);CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,                                      frameWidth,                                      frameHeight,                                      kCVPixelFormatType_32ARGB,                                      (__bridge CFDictionaryRef) options,                                      &pxbuffer);NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);CVPixelBufferLockBaseAddress(pxbuffer, 0);void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);NSParameterAssert(pxdata != NULL);CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();CGContextRef context = CGBitmapContextCreate(pxdata,                                             frameWidth,                                             frameHeight,                                             8,                                             CVPixelBufferGetBytesPerRow(pxbuffer),                                             rgbColorSpace,                                             (CGBitmapInfo)kCGImageAlphaNoneSkipFirst);NSParameterAssert(context);CGContextConcatCTM(context, CGAffineTransformIdentity);CGContextDrawImage(context, CGRectMake(0,                                       0,                                       frameWidth,                                       frameHeight),                   image);CGColorSpaceRelease(rgbColorSpace);CGContextRelease(context);CVPixelBufferUnlockBaseAddress(pxbuffer, 0);return pxbuffer;

}

2 0
原创粉丝点击