核心图形:如何同时绘制多个实例?

时间:2014-04-02 13:21:28

标签: objective-c macos cocoa core-graphics

我有一个绘制图像的类。对于多个图像源,它被多次实例化,并且可以同时具有多个这些对象;每个都获得一个中断驱动的馈送(来自USB设备)。

该类的部分功能是注释所输入的图像,因此有一个例程可以执行一些标准的Core Graphics内容来添加注释。

我通过位图上下文执行此操作,首先使用标准CGContext内容绘制图像,然后添加注释。

问题在于,当我这样做时,来自多个来源的图像彼此重叠。它看起来像一个既定的背景;即使是位图上下文,也不是线程安全的。但是,我添加了NSLock,并没有解决问题,因此它可能不仅仅是线程安全问题。

这是例程的简化版本:

- (CGImageRef)createCopiedImage:(CGImageRef)inImage
{
    CGImageRef  ret = nil;

    CGRect  imageRect = CGRectMake ( 0, 0, CGImageGetWidth ( ret ), CGImageGetHeight ( ret ) );
    size_t  rowBytes = imageRect.size.width * 4;
    size_t  bufferLen = rowBytes * imageRect.size.height;
    void    *buffer = malloc ( bufferLen );

    if ( buffer )
    {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB );

        if ( colorSpace )
        {
        CGContextRef    drawingContext = CGBitmapContextCreate ( buffer, imageRect.size.width, imageRect.size.height, 8, rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst );

        if ( drawingContext )
        {
            CGContextDrawImage ( drawingContext, imageRect, inImage );

            CFRelease ( backGroundImage );


            // DO ANNOTATION STUFF HERE

            CGDataProviderRef dataProvider = CGDataProviderCreateWithData ( NULL, buffer, rowBytes * imageRect.size.height, NULL );

            if ( dataProvider )
            {
                CGImageRef  ret = CGImageCreate ( imageRect.size.width, imageRect.size.height, 8, 32, rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst, dataProvider, NULL, false, kCGRenderingIntentDefault );

                CGDataProviderRelease ( dataProvider) ;
            }

            CGContextRelease ( drawingContext );
        }

    free ( buffer );
    }

    return ret;
}

关于如何避免这些情况相互踩踏的任何想法?

1 个答案:

答案 0 :(得分:1)

不能承受内存泄漏,您应该能够让系统为您处理内存分配,并使用新创建的图形来复制出CGImageRef:

@implementation YourClass

- (CGImageRef)createCopiedImage:(CGImageRef)inImage
{
    CGImageRef  ret = NULL;

    CGRect  imageRect = CGRectMake ( 0, 0, CGImageGetWidth ( ret ), CGImageGetHeight ( ret ) );
    size_t  rowBytes = imageRect.size.width * 4;
    size_t  bufferLen = rowBytes * imageRect.size.height;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB );

    if ( colorSpace )
    {
        CGContextRef drawingContext = CGBitmapContextCreate ( NULL, imageRect.size.width, imageRect.size.height, 8, rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst );

        if ( drawingContext )
        {
            CGContextDrawImage ( drawingContext, imageRect, inImage );

            CFRelease ( backGroundImage );

            // DO ANNOTATION STUFF HERE

            // Copy image out
            ret = CGBitmapContextCreateImage(drawingContext);

            CGContextRelease ( drawingContext );
        }
    }

    return ret;
}

@end