0

谁能给我有关如何在使用 ARC 时从图像(NSImage 或图像文件)正确创建 OpenGL 纹理的信息?我尝试使用 CGImage(类似于 CGImageSource->CGImage->GLubyte ...),但这导致了相当大的内存泄漏。

示例代码:

    _bottom_source = CGImageSourceCreateWithData((__bridge CFDataRef)[_bottom_layer_image TIFFRepresentation], NULL);
    _bottom_cgimage =  CGImageSourceCreateImageAtIndex(_bottom_source, 0, NULL);
    _cg_bottom_image_width = CGImageGetWidth(_bottom_cgimage);
    _cg_bottom_image_height = CGImageGetHeight(_bottom_cgimage);
    _bottom_image_data = (GLubyte *) calloc(_cg_bottom_image_width * _cg_bottom_image_height * 4, sizeof(GLubyte));
    _bottom_context = CGBitmapContextCreate(_bottom_image_data, _cg_bottom_image_width, _cg_bottom_image_height, 8, _cg_bottom_image_width * 4, CGImageGetColorSpace(_bottom_cgimage), kCGImageAlphaPremultipliedLast);
    CGContextDrawImage(_bottom_context, CGRectMake(0.0, 0.0, (CGFloat)_cg_bottom_image_width, (CGFloat)_cg_bottom_image_height), _bottom_cgimage);
    CGContextRelease(_bottom_context);

    CIImage *_gray_out_ciimage = [[CIImage alloc] initWithCGImage:_bottom_cgimage];
    CIFilter *gray_out_filter = [CIFilter filterWithName:@"CIColorControls"];
    [gray_out_filter setDefaults];
    [gray_out_filter setValue:_gray_out_ciimage forKey:@"inputImage"];
    [gray_out_filter setValue:0 forKey:@"inputSaturation"];
    _gray_out_ciimage = [gray_out_filter valueForKey:@"outputImage"];
    NSBitmapImageRep *_temporaryRep = [[NSBitmapImageRep alloc] initWithCIImage:_gray_out_ciimage];

    _top_cgimage = _temporaryRep.CGImage;
    _cg_top_image_width = CGImageGetWidth(_top_cgimage);
    _cg_top_image_height = CGImageGetHeight(_top_cgimage);
    _top_image_data = (GLubyte *) calloc(_cg_top_image_width * _cg_top_image_height * 4, sizeof(GLubyte));
    _top_context = CGBitmapContextCreate(_top_image_data, _cg_top_image_width, _cg_top_image_height, 8, _cg_top_image_width * 4, CGImageGetColorSpace(_top_cgimage), kCGImageAlphaPremultipliedLast);
    CGContextDrawImage(_top_context, CGRectMake(0.0, 0.0, (CGFloat)_cg_top_image_width, (CGFloat)_cg_top_image_height), _top_cgimage);
    CGContextRelease(_top_context);
//wielding *_image_data as OpenGL textures images and after that:
    CGImageRelease(_bottom_cg_image);
    CGImageRelease(_top_cg_image);
    free(_bottom_image_data);
    free(_top_image_data);

it acts like that:
That code, that I have written in question now works like that:

1. I launch app. In activity monitor `Real Mem:78MB` and `Virtual Mem: 120MB`.
2. I load 389kb image. In activity monitor now `Real Mem:181.3MB` and `Virtual Mem:161.1MB`.
3. Then I load 5.3MB image. And now in activity monitor `Real Mem: 519MB` and `Virtual Mem: 456.8MB` 
4. If I repeat step 2 now again, `Real Mem:468.5MB` and `Virtual Mem: 436.5 MB`.

And all the time when I load image, memory consumption is increasing, not getting lower. It gets a little bit lower only if I load much smaller image than the image that is already loaded (app works so that only one image can be loaded at one time). 

然后我尝试使用 NSImage 到 NSBitmapImageRep 方法。它几乎没有内存泄漏,但是在使用它时我遇到了更高 DPI 图像的问题。那么如何在没有任何内存泄漏和尽可能小的内存消耗的情况下正确地做到这一点呢?

4

1 回答 1

1

看起来您正在分配,但没有释放_bottom_source_gray_out_ciimage(至少在您发布的代码中)。

于 2012-11-20T15:47:25.013 回答