如何在 iOS 中发布 CGImageRef

2023-11-30

我正在编写这个方法来计算图像的平均 R、G、B 值。以下方法将 UIImage 作为输入并返回包含输入图像的 R、G、B 值的数组。但我有一个问题:如何/在哪里正确释放 CGImageRef?

-(NSArray *)getAverageRGBValuesFromImage:(UIImage *)image
{
    CGImageRef rawImageRef = [image CGImage];

    //This function returns the raw pixel values
    const UInt8 *rawPixelData = CFDataGetBytePtr(CGDataProviderCopyData(CGImageGetDataProvider(rawImageRef)));

    NSUInteger imageHeight = CGImageGetHeight(rawImageRef);
    NSUInteger imageWidth = CGImageGetWidth(rawImageRef);

    //Here I sort the R,G,B, values and get the average over the whole image
    int i = 0;
    unsigned int red = 0;
    unsigned int green = 0;
    unsigned int blue = 0;

    for (int column = 0; column< imageWidth; column++)
    {
        int r_temp = 0;
        int g_temp = 0;
        int b_temp = 0;

        for (int row = 0; row < imageHeight; row++) {
            i = (row * imageWidth + column)*4;
            r_temp += (unsigned int)rawPixelData[i];
            g_temp += (unsigned int)rawPixelData[i+1];
            b_temp += (unsigned int)rawPixelData[i+2];

        }

        red += r_temp;
        green += g_temp;
        blue += b_temp;

    }

    NSNumber *averageRed = [NSNumber numberWithFloat:(1.0*red)/(imageHeight*imageWidth)];
    NSNumber *averageGreen = [NSNumber numberWithFloat:(1.0*green)/(imageHeight*imageWidth)];
    NSNumber *averageBlue = [NSNumber numberWithFloat:(1.0*blue)/(imageHeight*imageWidth)];


    //Then I store the result in an array
    NSArray *result = [NSArray arrayWithObjects:averageRed,averageGreen,averageBlue, nil];


    return result;
}

我尝试了两件事: 选项1: 我保持原样,但几个周期(5+)后程序崩溃,并且出现“内存不足警告错误”

选项2: 我添加一行 CGImageRelease(rawImageRef) 在方法返回之前。现在它在第二个周期后崩溃,我收到传递给该方法的 UIImage 的 EXC_BAD_ACCESS 错误。当我尝试在 Xcode 中分析(而不是运行)时,我在这一行收到以下警告 “调用者此时不拥有的对象的引用计数的错误递减”

我应该在哪里以及如何释放 CGImageRef?

Thanks!


正如其他人所说,您的内存问题是由复制的数据引起的。但这里有另一个想法:使用 Core Graphics 的优化像素插值来计算平均值。

  1. 创建 1x1 位图上下文。
  2. 将插值质量设置为中等(见下文)。
  3. 将图像缩小到这一像素。
  4. 从上下文缓冲区读取 RGB 值。
  5. (当然,要释放上下文。)

这可能会带来更好的性能,因为核心显卡经过高度优化,甚至可能使用 GPU 进行缩减。

测试表明,中等质量似乎通过取颜色值的平均值来插值像素。这就是我们想要的。

至少值得一试。

Edit:好吧,这个想法看起来太有趣了,值得尝试一下。所以这是一个示例项目显示差异。以下测量值是使用包含的 512x512 测试图像进​​行的,但您可以根据需要更改图像。

通过迭代图像数据中的所有像素来计算平均值大约需要 12.2 毫秒。绘制到一个像素的方法需要 3 毫秒,因此速度大约快 4 倍。使用时似乎会产生相同的结果kCGInterpolationQualityMedium.

我认为巨大的性能增益是 Quartz 注意到它不必完全解压缩 JPEG 而只使用 DCT 的低频部分的结果。当组合比例低于 0.5 的 JPEG 压缩像素时,这是一个有趣的优化策略。但我只是在这里猜测。

有趣的是,当使用你的方法时,70%的时间花在CGDataProviderCopyData而像素数据遍历只占30%。这暗示 JPEG 解压缩花费了大量时间。

Pixel Iterating Screenshot Draw-To-One-Pixel Screenshot

Note: 这是迟来的跟进在上面的示例图像上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 iOS 中发布 CGImageRef 的相关文章

随机推荐

  • 如何在异步任务中拥有舒适的(例如 GNU-readline 样式)输入行?

    我有一个异步程序 有两个任务 任务 1 做了一些工作 任务2提供命令行界面 CLI 它读取用户的命令并将其发送给任务1进行处理 CLI 基本上是一个循环 从连接到标准输入的异步流中读取行 它可以工作 但不是很舒服 问题是输入行不提供除 BA
  • GTSummary 中的行分组

    我正在尝试对一些行 变量 分类变量和连续变量 进行分组 以帮助提高大型数据集中的表可读性 这是虚拟数据集 library gtsummary library tidyverse library gt set seed 11012021 Cr
  • 如何使用特征对象来引用具有泛型方法的结构

    关于这个问题 将闭包存储在 HashMap 中 我了解到正确地将闭包传递给函数需要该函数是通用的 并且采用任何实现 Fn FnMut 或 FnOnce 特征的类型 在实现 C 库的一部分作为学习练习时 我需要某种类似这样的类型抽象 use
  • R 中的意外符号请参阅代码

    我试图编写一个函数来解析和合并一些数据 但是 R 抛出了意外的符号错误异常 我尝试了不同的方法来解决这个问题 仍然不起作用 请帮忙 see code aggall function df grp numcols sapply df clas
  • SqlDependency.OnChange 未在 WinForm 中触发?

    I used 使用 SqlDependency 检测更改作为我正在编写的代码的示例 我还查看了具有类似代码的其他链接 但它们都不起作用 本质上 我只是想改变label1 Text当表发生更改时 ErrorLog 因为某些原因 OnDepen
  • Node.js 到 MongoDB:按日期查找

    从 Node 到 MongoDB 查找日期出现问题 有人说 MongoDB 可能不是存储日期对象 而是存储字符串 但我不确定如何检查或如何修复它 在我的 Turnys js 文件中 exports findNeededTurnys func
  • 如何在 Python 中将条件语句与 for 循环结合起来?

    我有一个简单的例子 我认为在 Python 中可以用最少的努力将 if 语句和 for 循环结合起来 鉴于 sublists number1 number2 number3 for sublist in sublists if sublis
  • 从 NSString 获取 ivar 或属性

    我们能得到一个ivar or a property from a NSString就像我们可以得到一个class from a NSString与功能NSClassFromNSString 对于任何属性 您都可以使用 object valu
  • 手机号码验证安卓

    我想通过从用户的手机发送短信来将手机号码验证集成到我的 Android 应用程序中 那么除了向用户的手机发送短信之外 是否有任何 API 允许通过发送短信来验证手机号码 我建议cognalys for android 演示应用程序可在应用商
  • 使用scanf()输入字符的问题

    我正在尝试将一个字符输入到链接列表中 其中该字符可以是 A a G g T t C 或 c 我还不熟悉 C 我知道我在这里搞砸了一些事情 do printf nEnter a new nucleotide n scanf c newChar
  • BigQuery SQL 排除不在空结果中

    我遇到了不返回任何值的问题 数据库中有符合此条件的帐户 有点困惑为什么他们没有被退回 有什么建议么 select accountid from table1 where not in select accountid from table1
  • 如何构建 cURL 并在 Code::Blocks 项目中使用它(静态)

    我知道有很多关于此的主题 但它们都没有帮助我解决我的问题 我只想做一个简单的C 程序使用cURL with 静态库卷曲 没有 DLL 文件 上代码 块 Windows 8 我花了大约 20 个小时尝试这样做 但我发现的都是无用的东西和我不明
  • 位置:Windows Phone 7 中固定

    我正在尝试创建 PhoneGap Windows Phone 7 应用程序 为了模仿应始终在横向屏幕左侧可见的应用程序栏 我想放置一个 div CSS 为position fixed 然而 这不起作用 因为 WP7 上的 IE 似乎不支持它
  • 是否可以使用 MTOM 来响应 CXF RESTful Web 服务

    我在用着CXF 2 2 12我的 Web 服务的库 是否可以使用MTOM 消息传输优化机制 in RESTful回复 希望有任何与此相关的文档 教程的链接 谢谢 MTOM 是特定于 SOAP 的 因此我认为它与 RESTful 架构不兼容
  • 从张量的每个正面切片中提取对角线元素

    我有一个 p p n 张量 我想提取每个 p by p 切片的对角线元素 有谁知道如何在不循环的情况下做到这一点 谢谢 Behold永远强大 永远强大bsxfun for vectorizing MATLAB problems使用非常有效地
  • 如何在IOS sdk(Objective-c)中序列化一个类?

    如何在 Objective C 中序列化以下类 以便它可以与 SBJson 一起使用 当我使用此代码时 出现 动物不支持 JSON 序列化 错误 有人可以指出我哪里出错了吗 Animal h文件的内容如下 import
  • 如何通过publishAdd()通知获取添加的记录(不仅仅是id)?

    Each Sails js模型有方法publishAdd 当新记录添加到关联模型时 这会通知每个侦听器 此通知不包含新创建的记录 所以我必须从客户端发起另一个请求来获取新记录 Sails js 是否有可能发送带有通知的新记录 以便我可以减少
  • 在 java 中完成 FTP 后创建 0 kb 文件

    我正在尝试将文件通过 FTP 传输到远程计算机上 下面是我的代码 FTPClient ftpClient new FTPClient ftpClient connect home abc com ftpClient login remote
  • 如何在文本框中仅允许整数? [复制]

    这个问题在这里已经有答案了 在我的表单中 我希望仅允许在文本框中输入整数值 怎么做 您可以为此使用正则表达式验证器 下面是示例代码
  • 如何在 iOS 中发布 CGImageRef

    我正在编写这个方法来计算图像的平均 R G B 值 以下方法将 UIImage 作为输入并返回包含输入图像的 R G B 值的数组 但我有一个问题 如何 在哪里正确释放 CGImageRef NSArray getAverageRGBVal