为什么这个GLView截图代码返回空白/黑色UIImage?

时间:2012-06-23 10:09:42

标签: iphone objective-c ios xcode opengl-es

我使用以下代码截取GLView中的像素截图。问题是,它返回一个完全黑色的UIImage。此代码在LineDrawer.m中调用,GLView- (UIImage*) getGLScreenshot { NSLog(@"1"); float scale = 0.0; if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { // scale value should be 1.0 on 3G and 3GS, and 2.0 on iPhone 4. scale = [[UIScreen mainScreen] scale]; } // these are swapped since the screen is rotatey float h = 768 * scale; float w = 924 * scale; NSInteger myDataLength = w * h * 4; // allocate array and read pixels into it. GLubyte *buffer = (GLubyte *) malloc(myDataLength); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer); // gl renders "upside down" so swap top to bottom into new array. // there's gotta be a better way, but this works. GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); for(int y = 0; y <h; y++) { for(int x = 0; x <w * 4; x++) { buffer2[(((int)h-1) - y) * (int)w * 4 + x] = buffer[y * 4 * (int)w + x]; } } // make data provider with data. CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); // prep the ingredients int bitsPerComponent = 8; int bitsPerPixel = 32; int bytesPerRow = 4 * w; CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; // make the cgimage CGImageRef imageRef = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); // then make the uiimage from that UIImage *myImage = [UIImage imageWithCGImage:imageRef]; return myImage; } - (void)saveGLScreenshotToPhotosAlbum { UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil); } 代码的核心 - 所以它是从右侧.m文件中调用的。如何保存实际屏幕截图而不是黑色图像?

{{1}}

3 个答案:

答案 0 :(得分:1)

我不得不在麻雀框架中做类似的事情前一段时间,你应该能够从这个论坛回复的代码中提取你需要的部分: http://forum.sparrow-framework.org/topic/spdisplayobjectscreenshot

编辑:此帖http://forum.sparrow-framework.org/topic/taking-screenshots

答案 1 :(得分:0)

更改您的可绘制属性

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

            [NSNumber numberWithBool:YES],  
                kEAGLDrawablePropertyRetainedBacking, 
                kEAGLColorFormatRGB565, 
                kEAGLDrawablePropertyColorFormat, nil];

kEAGLDrawablePropertyRetainedBacking为YES

答案 2 :(得分:0)

尝试这个我经历了很多事情,最后找到了解决方案。

-(UIImage*)renderImg{
        GLint backingWidth = 0;
        GLint backingHeight = 0;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
        GLubyte *buffer = (GLubyte *) malloc(backingWidth * backingHeight * 4);
        GLubyte *buffer2 = (GLubyte *) malloc(backingWidth * backingHeight * 4);

        glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                     (GLvoid *)buffer);
        for (int y=0; y<backingHeight; y++) {
            for (int x=0; x<backingWidth*4; x++) {
                buffer2[y * 4 * backingWidth + x] =
                buffer[(backingHeight - y - 1) * backingWidth * 4 + x];
            }
        }
        free(buffer);
        CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2,
                                                                  backingWidth * backingHeight * 4,
                                                                  myProviderReleaseData);
        // set up for CGImage creation
        int bitsPerComponent = 8;
        int bitsPerPixel = 32;
        int bytesPerRow = 4 * backingWidth;
        CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
        // Use this to retain alpha
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
        CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
        CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight,
                                            bitsPerComponent, bitsPerPixel,
                                            bytesPerRow, colorSpaceRef,
                                            bitmapInfo, provider,
                                            NULL, NO,
                                            renderingIntent);
        // this contains our final image.
        UIImage *newUIImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
        CGColorSpaceRelease(colorSpaceRef);
        CGDataProviderRelease(provider);

        return newUIImage;
    }

我认为它应该完美无缺。