内存泄漏CGBitmapContextCreateImage

时间:2012-11-12 16:49:48

标签: iphone memory-leaks uiimage

在Instruments中,它告诉我在resizedImage方法中有一个由CGBitmapContextCreateImage引起的泄漏。然而经过大量的研究和反复试验后,我得出的结论是它是在调用链的其他地方引起的。

呼叫链如下:
takeFoto - > saveFoto - > setImage_bg - > bolly - > resizedImage

以下是所有相关代码

-(void)takeFoto

{
[stillImageOutput captureStillImageAsynchronouslyFromConnection:self.videoConnection completionHandler:
 ^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
{
    NSData* idata = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];//[od copy];

    UIImage *image = [UIImage imageWithData:idata];

    CGImageRef cgi = [image CGImage];

    CGImageRef cgi2 = CGImageCreateWithImageInRect(cgi, CGRectMake(0, 0, CGImageGetWidth(cgi), CGImageGetHeight(cgi));


    UIImageOrientation iori;
    if(self.devOri==UIInterfaceOrientationLandscapeRight)
    {
        if([self isFrontCamera]) iori = UIImageOrientationDownMirrored;
        else iori = UIImageOrientationUp;
    }
    else if(self.devOri==UIInterfaceOrientationLandscapeLeft)
    {
        if([self isFrontCamera]) iori = UIImageOrientationUpMirrored;
        else iori = UIImageOrientationDown;
    }
    else if(self.devOri==UIInterfaceOrientationPortraitUpsideDown)
    {
        if([self isFrontCamera]) iori = UIImageOrientationRightMirrored;
        else iori = UIImageOrientationLeft;
    }
    else
    {
        if([self isFrontCamera]) iori = UIImageOrientationLeftMirrored;
        else iori = UIImageOrientationRight;
    }
    UIImage *scaledImage = [[UIImage alloc] initWithCGImage:cgi2 scale:1 orientation:iori];

    CGImageRelease(cgi2);

    self.foto = scaledImage;
    [scaledImage release];

    [parent saveFoto];
 }];
}


-(void)saveFoto
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

[self setImage_bg:captureManager.foto];

[pool release];
}


-(void)setImage_bg:(UIImage*)oimg
{
CGSize sz = savePreview.frame.size;
UIImage* img = [oimg copy];

[savePreview setImage:[filters resizeImage:img size:sz]];

sz = CGSizeMake(64, 64);
UIImage* img2 = [filters resizeImage:img size:sz]; 

bolPrv.image = [filters bolly:img2];

[img release];
}


//filters bolly
-(UIImage*)bolly:(UIImage*)img
{
CIImage *beginImage = [CIImage imageWithCGImage:img.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];

UIImage* bb = [UIImage fromFile:@"bollywoodBlend3.png"];
UIImage* bb2 = [bb resizedImage:img.size interpolationQuality:kCGInterpolationMedium];
CIFilter *filter = [CIFilter filterWithName:@"CIOverlayBlendMode"
                              keysAndValues: kCIInputImageKey, beginImage,
                    @"inputBackgroundImage", [CIImage imageWithCGImage:bb2.CGImage], nil];
CIImage *outputImage = filter.outputImage;

filter = [CIFilter filterWithName:@"CIColorControls"
                    keysAndValues: kCIInputImageKey, outputImage,
          @"inputSaturation", [NSNumber numberWithFloat:1.8],
          @"inputBrightness", [NSNumber numberWithFloat:0.1],
          @"inputContrast", [NSNumber numberWithFloat:1.5],
           nil];
outputImage = filter.outputImage;

CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg =  [UIImage imageWithCGImage:cgimg];

CGImageRelease(cgimg);

return [newImg autorelease];
}



// filters resizeImage (same code used for resizedImage)
- (UIImage *)resizeImage:(UIImage*)img size:(CGSize)newSize
{
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = img.CGImage;

// Build a context that's the same dimensions as the new size
CGColorSpaceRef csr = CGImageGetColorSpace(imageRef);
CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            4*newRect.size.width,
                                            csr,
                                            CGImageGetBitmapInfo(imageRef));

// Draw into the context; this scales the image
CGContextDrawImage(bitmap, newRect, imageRef);

//    CGImageSourceCreateThumbnailAtIndex

// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:img.scale orientation:img.imageOrientation];

// Clean up
CGImageRelease(newImageRef);
CGContextRelease(bitmap);

return newImage;
}


- (UIImage *)resizedImage:(CGSize)newSize
            transform:(CGAffineTransform)transform
       drawTransposed:(BOOL)transpose
 interpolationQuality:(CGInterpolationQuality)quality 
{
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
CGImageRef imageRef = self.CGImage;

// Build a context that's the same dimensions as the new size
CGColorSpaceRef csr = CGImageGetColorSpace(imageRef);
CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            4*newRect.size.width,
                                            csr,
                                            CGImageGetBitmapInfo(imageRef));

// Rotate and/or flip the image if required by its orientation
CGContextConcatCTM(bitmap, transform);

// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(bitmap, quality);

// Draw into the context; this scales the image
CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);

//    CGImageSourceCreateThumbnailAtIndex

// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

// Clean up
CGImageRelease(newImageRef);
CGContextRelease(bitmap);

return newImage;
 }

// UIImage from file
+(UIImage*)fromFile:(NSString*)fname
{
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", bundlePath,fname]];
}

0 个答案:

没有答案