重要经验八---UIImage转换为CVPixelBufferRef
2016-05-26 16:01
519 查看
照片时间,是我个人开发的一款显示照片拍摄时间的应用,实用、免费、体积小。
http://itunes.apple.com/app/id571238224
最近做一个视频处理的项目(Rokk!),需要将opengl渲染后的特效保存为视频,由于使用了第三方库,所以不能直接使用opengl的framebuffer,后面使用了一种比较蛋疼的方式:使用glReadPixels来读取每一个渲染帧,转换为UIImage,然后将UIImage转换为CVPixelBufferRef,使用AVAssetWriterInputPixelBufferAdaptor和AVAssetWriter保存CVPixelBufferRef,最后生成视频。【此处应该有很多改进空间,希望能够多多交流】。
在上述过程中,遇到了很多坑,其中就包含“UIImage转换为CVPixelBufferRef”,网上有蛮多关于这方面的代码的,但是真正没有什么bug的,太少了,综合了各家的代码,最终我得到了相对比较正确、简洁的代码:
- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image{
}
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;
}
相关文章推荐
- Vue.js-----轻量高效的MVVM框架(十一、使用slot分发内容)
- iOS读取图片数据的两种方法:UIImageJPEG和UIImagePNG
- 关于UI界面上的坐标
- UIScrollView属性
- UIView层次管理
- 用户账号-用户标识符:UID与GID
- 严重: Exception occurred during processing request: Position beyond number of declared ordinal paramet
- ngui 和粒子层级问题
- Cell简介和UITableViewCell的contentView
- UGUI里面button的移动
- iOS UITableView - beginUpdates和endUpdates方法说明
- UGUI的下拉菜单
- iOS开发之窥探UICollectionViewController(五) --一款炫酷的图片浏览组件
- iOS开发之窥探UICollectionViewController(四) --一款功能强大的自定义瀑布流
- iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流
- iOS开发之窥探UICollectionViewController(一) -- Ready Your CollectionViewController
- priority_queue的使用
- Please use the /MD switch for _AFXDLL builds错误
- iOS开发之使用Storyboard预览UI在不同屏幕上的运行效果
- iOS开发之多线程技术(NSThread、OperationQueue、GCD)