gpt4 book ai didi

ios - 如何在 iOS 中发布 CGImageRef

转载 作者:技术小花猫 更新时间:2023-10-29 10:54:26 26 4
gpt4 key购买 nike

我正在编写此方法来计算图像的平均 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?

谢谢!

最佳答案

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

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

这可能会带来更好的性能,因为 Core Graphics 是高度优化的,甚至可能使用 GPU 进行缩小。

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

至少值得一试。

编辑:好吧,这个想法似乎太有趣了,不能不去尝试。所以here's an example project显示差异。以下测量是使用包含的 512x512 测试图像进​​行的,但您可以根据需要更改图像。

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

我假设巨大的性能提升是由于 Quartz 注意到它不必完全解压缩 JPEG,而是它可以仅使用 DCT 的较低频率部分。当合成比例低于 0.5 的 JPEG 压缩像素时,这是一个有趣的优化策略。但我只是在这里猜测。

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

Pixel Iterating Screenshot Draw-To-One-Pixel Screenshot

备注:Here's a late follow up在上面的示例图片上。

关于ios - 如何在 iOS 中发布 CGImageRef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12147779/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com