2012-09-21 24 views
18

Im Folgenden ist der Code verwende ich ein Bild von einer OpenGL ES Szene zum Lesen:Warum funktioniert glReadPixels() in diesem Code in iOS 6.0 nicht?

-(UIImage *)getImage{ 

    GLint width; 

    GLint height; 

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); 

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); 


    NSLog(@"%d %d",width,height); 

    NSInteger myDataLength = width * height * 4; 

    // allocate array and read pixels into it. 
    GLubyte *buffer = (GLubyte *) malloc(myDataLength); 
    glReadPixels(0, 0, width, height, 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 < height; y++) 
     { 
     for(int x = 0; x < width * 4; x++) 
      { 
      buffer2[((height - 1) - y) * width * 4 + x] = buffer[y * 4 * width + 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 * width; 
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 

    // make the cgimage 
    CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 

    // then make the uiimage from that 
    UIImage *myImage = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 
    CGDataProviderRelease(provider); 
    CGColorSpaceRelease(colorSpaceRef); 
    free(buffer); 
    free(buffer2); 
    return myImage; 

} 

Dies ist in iOS 5.x und niedrigeren Versionen arbeiten, aber auf iOS 6.0 dies nun ein schwarzes Bild zurück. Warum schlägt glReadPixels() auf iOS 6.0 fehl?

+0

hm, mein Aussehen, die dasselbe und funktioniert, außer 'GLint Ansichtsfenster [4]; glGetIntegerv (GL_VIEWPORT, Ansichtsfenster); int width = Ansichtsfenster [2]; int height = Ansichtsfenster [3]; ' – SAKrisT

+0

funktioniert dein Code? – GameLoading

+0

@SAKrisT in iOS 6? – GameLoading

Antwort

25
CAEAGLLayer *eaglLayer = (CAEAGLLayer *) self.layer; 
eaglLayer.drawableProperties = @{ 
    kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES], 
    kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8 
}; 

gesetzt
kEAGLDrawablePropertyRetainedBacking = YES 

(ich weiß nicht, warum dieser Tipp gut ../// wird)

+2

Ich weiß auch nicht, wie es funktioniert Aber es funktioniert einfach: D – GameLoading

+10

Der Grund ist wahrscheinlich, dass Sie ' Wieder versuchen, vom Bildschirm zu lesen, nachdem der Inhalt mit '[context presentRenderbuffer: GL_RENDERBUFFER];'. Sofern Sie nicht wie oben festgelegt haben, dass der Layer die beibehaltene Hintergrundebene verwendet, können Sie nicht davon ausgehen, dass dieser Inhalt nach der Präsentation beibehalten wird. Es scheint, dass iOS 6.0 diesen Inhalt aggressiver entfernt, nachdem er nicht mehr benötigt wird. Das oben genannte Ergebnis führt zu einem Leistungseinbruch, sodass Sie besser eine 'glFinish()' -Operation ausführen und den Bildschirm danach erfassen und dann den Render-Puffer darstellen können. –

+1

Ich hatte eaglLayer.opaque = TRUE; in meinem Code, die auch verhindern, dass Screenshot-Code funktioniert, löschte ich eaglLayer.opaque = TRUE; und setze kEAGLDrawablePropertyRetainedBacking = YES. Jetzt funktioniert es. –

-4

bro versuchen Sie diese Methode, um Ihr Screenshot Bild zu bekommen. Das Ausgangsbild ist MailImage

- (UIImage*)screenshot 
{ 
    // Create a graphics context with the target size 
    // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration 
    // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext 
    CGSize imageSize = [[UIScreen mainScreen] bounds].size; 
    if (NULL != UIGraphicsBeginImageContextWithOptions) 
     UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0); 
    else 
     UIGraphicsBeginImageContext(imageSize); 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Iterate over every window from back to front 
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) 
    { 
     if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) 
     { 
      // -renderInContext: renders in the coordinate space of the layer, 
      // so we must first apply the layer's geometry to the graphics context 
      CGContextSaveGState(context); 
      // Center the context around the window's anchor point 
      CGContextTranslateCTM(context, [window center].x, [window center].y); 
      // Apply the window's transform about the anchor point 
      CGContextConcatCTM(context, [window transform]); 
      // Offset by the portion of the bounds left of and above the anchor point 
      CGContextTranslateCTM(context, 
            -[window bounds].size.width * [[window layer] anchorPoint].x, 
            -[window bounds].size.height * [[window layer] anchorPoint].y); 

      // Render the layer hierarchy to the current context 
      [[window layer] renderInContext:context]; 

      // Restore the context 
      CGContextRestoreGState(context); 
     } 
    } 

    // Retrieve the screenshot image 
    Mailimage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return Mailimage; 


} 
+0

es gibt mir den ganzen Bildschirm Bild mit Ausnahme des Bildes, das in Puffer ist – GameLoading

+1

Diese Antwort tut im Grunde alles außer was OP fragt ... –

Verwandte Themen