1.

    //设置CIContext,并从CIImage -> CGImage -> UIImage
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage: outputImage fromRect:qrRect];
UIImage *resultIamge = [UIImage imageWithCGImage:cgImage];
//(如果 直接用[UIImage imageWithCIImage:outputImage]; 会得到一个不是位图的图片)

还有一个,就是CIImage 只有经过context 转化为CGImage后,才能变成位图图片。(非位图图片,不能保存到相册,不能转换为NSData (jpeg png))

 
 
 2.
 
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v',表示输出的视频格式为NV12;范围: (luma=[16,235] chroma=[16,240])
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange = '420f',表示输出的视频格式为NV12;范围: (luma=[0,255] chroma=[1,255])
kCVPixelFormatType_32BGRA = 'BGRA', 输出的是BGRA的格式

https://www.jianshu.com/p/7da76246ce82

 
 
 kCVPixelFormatType_420YpCbCr8Planar = 'y420',
/* Planar Component Y'CbCr 8-bit 4:2:0. baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrPlanar struct */ kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v',
/* Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235] chroma=[16,240]). baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */ kCVPixelFormatType_420YpCbCr8BiPlanarFullRange = '420f',
/* Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255] chroma=[1,255]). baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
#YpCbCr

Y分量:Y,U分量:Cb,V分量:Cr。即YUV格式的数据。

#8-bit

并且每个点采用8bit来保存一个Y的亮度。

#4:2:0

YUV的详细格式为:4:2:0。

# baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrPlanar struct

YUV数据的地址在CVPlanarPixelBufferInfo_YCbCrPlanar中以大端的形式存储。

#Planar & Bi-Planar

第一个是Planar模式,第二个是BiPlanar模式。
Planar格式就是单平面模式,在这个模式下,一个buf存储所有的数据。将Y、U、V分量分别打包,依次存储。即YYYY...U...V...即I420.
BiPlanar格式就是双平面模式,在这个模式下,亮度和色度被分成两个buf来存储。将Y和UV分别打包,一次存储。即YYYY...UV...即NV12.

#VideoRange & FullRange

亮度和色度的取值为8位,即2^8 = 256即可取值为【0-255】
VideoRange能取的值宽度为【16-235】
FullRange能取得值宽度为【0-255】

#采集信息查看

查看采集到的信息。

CMSampleBufferGetFormatDescription(sampleBuffer);
#如何从采集的CMSampleBufferRef中取得YUV数据

转化为CVImageBufferRef:

CVImageBufferRef buffer = CMSampleBufferGetImageBuffer(sampleBuffer);

获取宽高:

CVPixelBufferGetWidth(pixelBuffer);
CVPixelBufferGetHeight(pixelBuffer);

取得YUV数据地址:

CVPixelBufferGetBaseAddressOfPlane(pixelBuffer,Plane_index);
//这里的Plane_index与上文的Plane模式相关
如果是Plane模式则直接取到所有数据
如果是BiPlane则需要分两次,即Plane_index=0取得Y分量地址与Plane_index=1取得UV分量的地址
#注意事项

在操作pixelBuffer的时候记得加上锁

    CVPixelBufferLockBaseAddress(pixelBuffer, lockFlag);
//在这里操作
CVPixelBufferUnlockBaseAddress(pixelBuffer, lockFlag);

 

3.

/**
* 把 CMSampleBufferRef 转化成 UIImage 的方法,参考自:
* https://stackoverflow.com/questions/19310437/convert-cmsamplebufferref-to-uiimage-with-yuv-color-space
* note1 : SDK要求 colorSpace 为 CGColorSpaceCreateDeviceRGB
* note2 : SDK需要 ARGB 格式的图片
*/
- (UIImage *) imageFromSamplePlanerPixelBuffer:(CMSampleBufferRef)sampleBuffer{
@autoreleasepool {
CMFormatDescriptionRef desc = CMSampleBufferGetFormatDescription(sampleBuffer);
NSLog(@">>%@",desc); // Get a CMSampleBuffer's Core Video image buffer for the media data
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, ); // Get the number of bytes per row for the plane pixel buffer
void *baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, ); // Get the number of bytes per row for the plane pixel buffer
size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,);
// Get the pixel buffer width and height
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer); uint8_t *rgbabuffer = baseAddress;
for (int y=; y<; y++) {
for (int x=; x<width;x++) {
rgbabuffer[y*bytesPerRow+x*+] = ;
rgbabuffer[y*bytesPerRow+x*+] = ;
rgbabuffer[y*bytesPerRow+x*+] = ;
rgbabuffer[y*bytesPerRow+x*+] = ;
}
} // Create a device-dependent RGB color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Create a bitmap graphics context with the sample buffer data
CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, ,
bytesPerRow, colorSpace, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little);
// Create a Quartz image from the pixel data in the bitmap graphics context
CGImageRef quartzImage = CGBitmapContextCreateImage(context);
// Unlock the pixel buffer
CVPixelBufferUnlockBaseAddress(imageBuffer,); // Free up the context and color space
CGContextRelease(context);
CGColorSpaceRelease(colorSpace); // Create an image object from the Quartz image
UIImage *image = [UIImage imageWithCGImage:quartzImage]; // Release the Quartz image
CGImageRelease(quartzImage);
return (image);
}
}
 
 

第31月第19天 NV12的更多相关文章

  1. 第3月第19天 cxx_destruct dispatch_get_main_queue()死锁

    1. http://blog.jobbole.com/65028/ 2. - (void)viewDidLoad { [super viewDidLoad]; NSLog("); dispa ...

  2. 第31月第25天 xcode debug 限制uitextfiled输入

    1.xcode debug 了解了每个设置的意思,个人觉得对于一个普通的app来说可以这样配置这些设置: Generate Debug Symbols:DEBUG和RELEASE下均设为YES(和Xc ...

  3. 第31月第17天 resolveInstanceMethod

    1. #import "UIView+Test.h" #import <objc/runtime.h> @implementation UIView (Test) + ...

  4. 第31月第15天 -fembed-bitcode

    1. 确保打包的时候使用的是fembed-bitcode, 而不是fembed-bitcode-maker fembed-bitcode-maker:只是简单的标记一下在archive出来的二进制中b ...

  5. 第31月第10天 tableview头部空白 Other Linker Flags rtmp

    1.ios10 tableview头部空白 if (@available(iOS 11.0, *)) { self.tableView.contentInsetAdjustmentBehavior = ...

  6. 第31月 第9天 责任链AppDelegate

    1.AppDelegate 到这里我们把解决方案再明确一下:把 AppDelegate 的调用解耦成一个 责任链 模型.并且满足以下特征: 每个模块都可以无限制的实现 AppDelegate 的方法. ...

  7. 第18月第19天 masonry等分 uilabel sizetofit

    1.masonry等分 mas_distributeViewsAlongAxis MASAxisTypeHorizontal 2.uilabel sizetofit +(CGSize)labSizeW ...

  8. 第8月第19天 django rest

    1. def retrieve(self, request, pk=None): try: book = Book.objects.get(book_id=pk) except Book.DoesNo ...

  9. 第7月第19天 swift on linux

    1. https://github.com/iachievedit/moreswift http://dev.iachieved.it/iachievedit/more-swift-on-linux/ ...

随机推荐

  1. docker-compose的安装和卸载

    使用docker-compose 可以轻松.高效的管理容器,它是一个用于定义和运行多容器 docker 的应用程序工具. 原文地址:代码汇个人博客 http://www.codehui.net/inf ...

  2. 自己实现一个nullptr

    一 具体实现 代码(c++) const class nullptr_t { public: template<class T> inline operator T*() const { ...

  3. [LeetCode] 19. 删除链表的倒数第N个节点

    题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/ 题目描述: 给定一个链表,删除链表的倒数第 n 个节点, ...

  4. master公式 ------ 求递归情况下的时间复杂度

    剖析递归行为和递归行为时间复杂度的估算一个递归行为的例子T(N) = a*T(N/b) + O(N^d)1) log(b,a) > d -> 复杂度为O(N^log(b,a))2) log ...

  5. css3动画和animate.css动画库使用

    CSS3动画 css3动画可以分为两种.transition过渡动画和keyframes关键帧动画 过渡动画 第一种叫过渡(transition)动画,就是从初始状态过渡到结束状态这个过程中所产生的动 ...

  6. js一些梳理

    浏览器组成 1.Shell部分2.内核内核的组成 1.渲染引擎 负责页面显示 2.JS引擎 3. 其他模块主流内核介绍 >> * Trident(IE内核) >> * Geck ...

  7. Unity TimeLine 资源结构

    ---恢复内容开始--- 先看一个TimeLine,如图 再来看看在Inspector中的PlayableDirector 其他参数字面意思很清楚了不再赘述,着重讲一下一个TimeLine绑定的资源. ...

  8. Pairwise 找到你的另一半

    都说优秀的程序员擅长面向对象编程,但却经常找不到另一半,这是为什么呢?因为你总是把自己局限成为一个程序员,没有打开自己的思维. 这是一个社群的时代啊,在这里你应该找到与你有相同价值观但又互补的另一半. ...

  9. Java Selenium中的几种等待方式

    Selenium自动化性能测试过程中,经常会出现取不到界面元素,主要原因是界面元素的加载与我们访问页面的时机不一致.可能是界面要素过多或者网络较慢,界面一直加载中:为了解决这种问题,selenium提 ...

  10. OO第一单元总结——多项式求导

    第一次作业分析 1.程序结构分析 类图: 好吧,这一次基本上完全是在面向过程编程,没有看出来任何的面向对象的特性. 复杂度: 可以看到模块间的相互耦合度很高,PolyDerive方法的非结构化程度也不 ...