我有一个类似于 GLPaint 示例的应用程序(但在 OpenGL ES 2.0 上)。我想在某些时候获取绘图视图的屏幕截图。我已经读过这个话题
但我不明白我应该在什么时候调用 CVOpenGLESTextureCacheCreate 并做其他事情。请问谁能帮帮我?
我有一个类似于 GLPaint 示例的应用程序(但在 OpenGL ES 2.0 上)。我想在某些时候获取绘图视图的屏幕截图。我已经读过这个话题
但我不明白我应该在什么时候调用 CVOpenGLESTextureCacheCreate 并做其他事情。请问谁能帮帮我?
我在您链接到的答案中描述的代码描述了像素缓冲区的创建、其匹配纹理的提取以及将该纹理绑定为帧缓冲区的输出。您使用该代码一次来设置您将渲染场景的帧缓冲区。
每当您想从该纹理中捕获时,您可能希望使用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。
另一种选择是:
祝你好运!
编辑
这可能行不通:我现在正在对其进行测试,并将尽快重新发布。
试试VTCreateCGImageFromCVPixelBuffer
(VideoToolbox
适用于 iOS 9.x+):
OSStatus VTCreateCGImageFromCVPixelBuffer(CVPixelBufferRef pixelBuffer, CFDictionaryRef options, CGImageRef _Nullable *imageOut);
Parameters
指定将成为 CGImage 图像数据源的像素缓冲区(设置options
为 NULL)。