2012-06-23 4 views
5

Ich verwende den folgenden Code, um einen Screenshot der Pixel in einem GLView zu machen. Das Problem ist, es gibt einen komplett schwarzen UIImage zurück. Dieser Code wird in LineDrawer.m aufgerufen, das das Herz des GLView-Codes ist - so wird es von der rechten .m-Datei aufgerufen. Wie kann ich den aktuellen Screenshot und kein schwarzes Bild speichern?Warum gibt dieser GLView Screenshot Code ein leeres/schwarzes UIImage zurück?

- (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); 
} 
+1

Sie benötigen zwei Puffer frei und lassen Sie die 'provider',' colorSpaceRef' und 'imageRef'. Wahrscheinlich können Sie auch den vertikalen Flip machen, indem Sie irgendwo einen negativen 'stride'-Wert angeben. – jhabbott

+0

Wie kann ich das tun? Tut mir leid, aber ich bin nicht so erfahren mit OpenGL und das ist eine Drop-in-Bibliothek! Ich würde mich über ein Beispiel freuen :-) –

+0

Mein Kommentar ist keine Antwort auf Ihre Frage, ich weise auf Ihre Speicherlecks hin. Sie sollten sich in CoreFoundation und Objective-C allgemein über das Reference Counting informieren. Außerdem müssen Sie bei der Verwendung von malloc auf die Speicherverwaltung in C achten. – jhabbott

Antwort

0

ändern Sie Ihre ziehbar Eigenschaften

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

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

kEAGLDrawablePropertyRetainedBacking auf YES