首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS -将UIImage转换为vImage内存处理

iOS -将UIImage转换为vImage内存处理
EN

Stack Overflow用户
提问于 2014-04-05 14:01:32
回答 2查看 2.5K关注 0票数 4

我有一个函数,可以将UIImage转换为vImage (用于iOS的Accelerate.framework中的一些vImage方法)。

我的方法是:

代码语言:javascript
复制
-(vImage_Buffer)convertImage:(UIImage *)image {
    CGImageRef sourceRef = [image CGImage];
    NSUInteger sourceWidth = CGImageGetWidth(sourceRef);
    NSUInteger sourceHeight = CGImageGetHeight(sourceRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(sourceData, sourceWidth, sourceHeight,
                                                       bitsPerComponent, sourceBytesPerRow, colorSpace,
                                                       kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big);
    CGContextDrawImage(context, CGRectMake(0, 0, sourceWidth, sourceHeight), sourceRef);
    CGContextRelease(context);
    vImage_Buffer v_image = {
        .data = sourceData,
        .height = sourceHeight,
        .width = sourceWidth,
        .rowBytes = sourceBytesPerRow
    };

    return v_image;
}

我是通过混合和匹配网络上的一些代码片段来构建的。

我的问题是,我有一个calloc调用,它为sourceData分配空间。但是,我该怎么释放这个记忆,在哪里释放呢?

考虑到我可能会多次调用这个方法,看起来就像-是的,会有一个巨大的内存泄漏。我认为我不会在这里发布它,因为它为我的vImage_Buffer变量提供了支持vImage_Buffer。但是我会在我的调用函数中释放它吗?或者将v_image设置为nil (或者在调用方法中指定返回的变量)最终释放calloc行分配的内存吗?

有人有指点吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-05 20:23:24

首先,您还需要通过调用colorSpace来发布CGColorSpaceRelease(colorSpace)

calloc分配的内存以后可以在调用函数中释放,使用free(v_image.data) (或者在调用方法中命名返回的变量)。

您还可以更改您的方法实现,以摆脱CGContext,并使用CGDataProviderRefCGImage获取字节--如下所示:

代码语言:javascript
复制
-(vImage_Buffer)convertImage:(UIImage *)image
{
    CGImageRef sourceRef = [image CGImage];
    NSUInteger sourceWidth = CGImageGetWidth(sourceRef);
    NSUInteger sourceHeight = CGImageGetHeight(sourceRef);

    CGDataProviderRef provider = CGImageGetDataProvider(sourceRef);
    CFDataRef bitmapData = CGDataProviderCopyData(provider);

    unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth;

    CFDataGetBytes(bitmapData, CFRangeMake(0, CFDataGetLength(bitmapData)), sourceData);

    vImage_Buffer v_image = {
        .data = (void *)sourceData,
        .height = sourceHeight,
        .width = sourceWidth,
        .rowBytes = sourceBytesPerRow
    };

    CFRelease(bitmapData);

    return v_image;
}

但是我没有检查表演。

我还建议将您的方法重命名为类似于vImageCreateFromImage的方法。您会意识到稍后您将负责清理内存。

票数 3
EN

Stack Overflow用户

发布于 2014-04-06 19:08:42

首先,也是最重要的是,iOS7.0 /OSX10.9大大简化了这一点,引入了vImageBuffer_InitWithCGImage函数(在vImage_Utilities.h中声明,头中有相当广泛的文档)。如果您不需要支持旧的OSes,您应该考虑使用这个新函数。

其次,无论是使用现有代码还是使用InitWithCGImage,一旦使用了以任何方式创建的vImage_Buffer对象,您都应该释放与数据字段相关的内存:free(buffer.data);

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22881875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档