0

我正在使用此功能来创建我的 IPAD 应用程序的屏幕截图。我在我的项目中使用 Sparrow 框架。SPDisplayObject 使用基于 OpenGl-ES 的渲染。

@implementation SPDisplayObject (ScreenshotFromSPDisplayObject)

- (UIImage *)getImageScreenshot{

int WIDTH = 1024;
int HEIGHT = 768;

CGSize size = CGSizeMake(WIDTH,HEIGHT);
//Create un buffer for pixels
GLuint bufferLenght=size.width*size.height*4;
GLubyte *buffer = (GLubyte *) malloc(bufferLenght);

//Read Pixels from OpenGL
glReadPixels(0,0,size.width,size.height,GL_RGBA,GL_UNSIGNED_BYTE,buffer);
//Make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLenght, NULL);

//Configure image
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * size.width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(size.width,size.height,bitsPerComponent,bitsPerPixel,bytesPerRow,colorSpaceRef,bitmapInfo,provider,NULL,NO,renderingIntent);

uint32_t *pixels = (uint32_t *)malloc(bufferLenght);
CGContextRef context = CGBitmapContextCreate(pixels, WIDTH, HEIGHT, 8, WIDTH*4, CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGContextTranslateCTM(context,0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, CGRectMake(0.0, 0.0, size.width, size.height), iref);
UIImage* screenshot = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];

UIGraphicsEndImageContext();

//free memory
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
CGImageRelease(iref);
CGContextRelease(context);
free(buffer);
free(pixels);

return screenshot;
}

@end

我从 UIViewController 像这样使用它:

@interface
    UIImageView *screenShot;
    UIImage *tempImage;

-(void) deactivePage
{
// attach screenshot
tempImage = [self.stage getImageScreenshot];
screenShot = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,1024,768)];
screenShot.image = tempImage;  
[self.view addSubview:screenShot];
}

- (void)dealloc 
{
screenShot.image = nil;
[screenShot removeFromSuperview];
[screenShot release];
[super dealloc];
}

UIViewController 被释放并释放 aprox。调用“deactivePage”函数 5 秒后。屏幕截图用于视图转换。

截屏就像一种魅力,但随着每个截屏,我的应用程序都会增长大约 10 MB,所以我可以这样做大约 15 次,直到应用程序崩溃。

那么泄漏点在哪里呢?我被卡住了.. :-(

4

2 回答 2

1

在 getImageScreenshot 函数中,您可以这样做:

UIImage* screenshot = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];

它创建一个 CGImageRef,然后从中创建(自动释放)一个 UIImage。这里发生的是这个 CGImageRef 仍然存在并且永远不会被释放,所以它正在泄漏。

相反,你应该做的是:


CGImageRef myCGImage = CGBitmapContextCreateImage(context);
UIImage* screenshot = [UIImage imageWithCGImage:myCGImage];
CGImageRelease(myCGImage);

您是否尝试过使用 Instruments(Leaks 或 Heapshots)查看它?您应该会看到这些 CGImareRef 元素仍然存在。

于 2011-02-26T16:56:08.843 回答
0

当它下降时,我看不到你在 UIViewController 中解除分配 tempImage 的位置。

于 2011-02-26T16:47:48.527 回答