Iphone 显示屏幕截图生成的UIImage未显示在UIImageView中(仅适用于设备)

Iphone 显示屏幕截图生成的UIImage未显示在UIImageView中(仅适用于设备),iphone,uiimage,opengl-es-2.0,glreadpixels,cgimageref,Iphone,Uiimage,Opengl Es 2.0,Glreadpixels,Cgimageref,我正在尝试将OpenGL缓冲区(视图中当前显示的内容)保存到设备的照片库中。下面的代码片段在模拟器上运行良好。但对于实际设备来说,它正在崩溃。我相信我创建从屏幕捕获的UIImage的方式可能有问题 此操作通过iAction事件句柄方法启动 我用来保存图像的函数是UIImageWriteToSavedPhotosAlbum(我最近将其更改为AlassetLibrary的writeImageToSavedPhotosAlbum) 我已确保我的应用程序被授权访问照片库 我还确保我的cgimagerd

我正在尝试将OpenGL缓冲区(视图中当前显示的内容)保存到设备的照片库中。下面的代码片段在模拟器上运行良好。但对于实际设备来说,它正在崩溃。我相信我创建从屏幕捕获的UIImage的方式可能有问题

  • 此操作通过iAction事件句柄方法启动
  • 我用来保存图像的函数是UIImageWriteToSavedPhotosAlbum(我最近将其更改为AlassetLibrary的writeImageToSavedPhotosAlbum)
  • 我已确保我的应用程序被授权访问照片库
  • 我还确保我的cgimagerd是全局定义的(在文件顶部定义的),并且我的UIImage是一个(非原子的,保留的)属性
有人能帮我解决这个问题吗?我想要一个从glReadPixels数据生成的有效UIImage引用

以下是相关代码段(调用以保存到照片库):

-(void)TakeImageBufferSnapshot:(CGSize)维度
{
NSLog(@“快照1:(%f,%f)”,dimensions.width,dimensions.height);
NSInteger尺寸=尺寸.宽度*尺寸.高度*4;
GLubyte*缓冲区=(GLubyte*)malloc(大小);
glReadPixels(0,0,dimensions.width,dimensions.height,GL_RGBA,GL_无符号字节,缓冲区);
GLubyte*buffer2=(GLubyte*)malloc(大小);
int height=(int)dimensions.height-1;
int width=(int)dimensions.width;
对于(int y=0;y
*更新* 我想我已经设法缩小了我的问题范围。我开始尝试出错,在注释了几行代码后运行应用程序(在设备上),以缩小范围。看起来我可能在TakeImageBufferSnapshot函数中遇到问题,该函数获取屏幕缓冲区(使用glReadPixels)并创建CGImageRef。现在,当我尝试使用[UIImage imageWithCGImage:]方法创建UIImage时,这似乎就是应用程序崩溃的原因。如果我将这一行注释掉,似乎没有问题(除了我没有UIImage引用这一事实)


我基本上需要一个有效的UIImage引用,这样我就可以将其保存到照片库(使用测试图像似乎可以正常工作)。

根据我的经验,您现在不能只获取缓冲区中的像素 您需要重新建立正确的上下文,然后在最终释放上下文之前进行绘制和抓取

=>这主要适用于设备,尤其是ios6

EAGLContext* previousContext = [EAGLContext currentContext];
[EAGLContext setCurrentContext: self.context];

    [self fillBuffer:sender];

    //GRAB the pixels here

    [EAGLContext setCurrentContext:previousContext];
或者(我就是这样做的)创建一个新的帧缓冲区,填充它并从那里抓取像素

GLuint rttFramebuffer;
glGenFramebuffers(1, &rttFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, rttFramebuffer);

[self fillBuffer:self.displayLink];

size_t size = viewportHeight * viewportWidth * 4;
GLubyte *pixels = malloc(size*sizeof(GLubyte));
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0, 0, viewportWidth, viewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

// Restore the original framebuffer binding
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glDeleteFramebuffers(1, &rttFramebuffer);

size_t bitsPerComponent = 8;
size_t bitsPerPixel = 32;
size_t bytesPerRow = viewportWidth * bitsPerPixel / bitsPerComponent;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, size, ImageProviderReleaseData);
CGImageRef cgImage = CGImageCreate(viewportWidth, viewportHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, provider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);

UIImage *image = [UIImage imageWithCGImage:cgImage scale:self.contentScaleFactor orientation:UIImageOrientationDownMirrored];
CGImageRelease(cgImage);
CGColorSpaceRelease(colorSpace);

编辑:删除了对presentBuffer的调用首先,我应该指出
glReadPixels()
的行为可能与预期不符。如果在调用
-presentRenderbuffer:
后尝试使用它从屏幕读取,则结果未定义。例如,在iOS 6.0+上,这将返回黑色图像。您需要使用
glReadPixels()
rig
GLuint rttFramebuffer;
glGenFramebuffers(1, &rttFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, rttFramebuffer);

[self fillBuffer:self.displayLink];

size_t size = viewportHeight * viewportWidth * 4;
GLubyte *pixels = malloc(size*sizeof(GLubyte));
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0, 0, viewportWidth, viewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

// Restore the original framebuffer binding
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glDeleteFramebuffers(1, &rttFramebuffer);

size_t bitsPerComponent = 8;
size_t bitsPerPixel = 32;
size_t bytesPerRow = viewportWidth * bitsPerPixel / bitsPerComponent;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, size, ImageProviderReleaseData);
CGImageRef cgImage = CGImageCreate(viewportWidth, viewportHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, provider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);

UIImage *image = [UIImage imageWithCGImage:cgImage scale:self.contentScaleFactor orientation:UIImageOrientationDownMirrored];
CGImageRelease(cgImage);
CGColorSpaceRelease(colorSpace);
rawImagePixels = (GLubyte *)malloc(totalBytesForImage);
glReadPixels(0, 0, (int)currentFBOSize.width, (int)currentFBOSize.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels);
dataProvider = CGDataProviderCreateWithData(NULL, rawImagePixels, totalBytesForImage, dataProviderReleaseCallback);
cgImageFromBytes = CGImageCreate((int)currentFBOSize.width, (int)currentFBOSize.height, 8, 32, 4 * (int)currentFBOSize.width, defaultRGBColorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaLast, dataProvider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
void dataProviderReleaseCallback (void *info, const void *data, size_t size)
{
    free((void *)data);
}