如何从Image正确创建OpenGL纹理?

时间:2012-11-16 15:23:21

标签: objective-c image macos opengl textures

任何人都可以向我提供有关如何在使用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图像问题。那么如何正确地做到这一点没有任何内存泄漏和尽可能小的内存消耗?

1 个答案:

答案 0 :(得分:1)

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