通过CVOpenGLESTextureCacheCreate获取屏幕截图

时间:2012-09-12 09:15:34

标签: ios opengl-es opengl-es-2.0

我有一个类似于GLPaint示例的应用程序(但在OpenGL ES 2.0上)。我希望在某些时刻获得绘图视图的屏幕截图。我已经阅读了这个topic

但我不明白我应该在什么时候调用CVOpenGLESTextureCacheCreate并做其他事情。谁可以帮助我?

3 个答案:

答案 0 :(得分:2)

我在您链接的the answer中描述的代码描述了像素缓冲区的创建,其匹配纹理的提取以及该纹理作为帧缓冲区输出的绑定。您可以使用该代码一次来设置将渲染场景的帧缓冲区。

每当你想要从那个纹理中捕获时,你可能想要使用glFinish()来阻止所有OpenGL ES渲染完成,然后使用我在那里描述的代码:

CVPixelBufferLockBaseAddress(renderTarget, 0);
_rawBytesForImage = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);
// Do something with the bytes
CVPixelBufferUnlockBaseAddress(renderTarget, 0);

提取包含场景图像的纹理的原始字节。

iOS纹理的内部字节顺序是BGRA,因此您需要使用以下内容从这些字节创建CGImageRef:

// It appears that the width of a texture must be padded out to be a multiple of 8 (32 bytes) if reading from it using a texture cache
NSUInteger paddedWidthOfImage = CVPixelBufferGetBytesPerRow(renderTarget) / 4.0;
NSUInteger paddedBytesForImage = paddedWidthOfImage * (int)currentFBOSize.height * 4;
dataProvider = CGDataProviderCreateWithData((__bridge_retained void*)self, _rawBytesForImage, paddedBytesForImage, dataProviderUnlockCallback);

cgImageFromBytes = CGImageCreate((int)currentFBOSize.width, (int)currentFBOSize.height, 8, 32, CVPixelBufferGetBytesPerRow(renderTarget), defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault);

在上面,我使用dataProviderUnlockCallback()函数来处理像素缓冲区的解锁和渲染的安全​​恢复,但是在你的情况下你可以忽略它,并且只为那里的参数传递NULL。 / p>

答案 1 :(得分:0)

另一种选择是:

  1. 创建新的CGBitmapContext
  2. 调用[layer renderInContext:yourNewContext]
  3. 从位图上下文获取CGImage
  4. 获取像素缓冲区,将CGImage放入其中,然后使用AVAdaptor将其附加到AssetWriter。
  5. 祝你好运!

    修改

    这可能不起作用:我现在正在测试它,并会尽快重新发布。

答案 2 :(得分:0)

试用with cte as ( select id, acronym, null as newid, id as baseid, 1 as lev, cast(id as varchar(max)) as ids from #GrwHist h where newid is null union all select h.id, h.acronym, h.newid, cte.baseid, cte.lev + 1 cte.ids + ',' + cast(h.id as varchar(max)) as ids from cte join #GrwHist h on h.new_id = cte.id ) select baseid, ids from (select cte.*, max(lev) over (partition by baseid) as maxlev from cte ) cte where maxlev = lev; select baseid, id from cte order by baseid; (适用于iOS 9.x +):

VTCreateCGImageFromCVPixelBuffer

指定将成为CGImage的图像数据源的像素缓冲区(将VideoToolbox设置为NULL)。