在我的项目中,我试图获得一系列UIImage
个对象的平均颜色。所以我实施了一个类别UIImage(AverageColor)
来计算平均颜色。
以下是我使用GPUImage
库的方式:
- (void)averageColor:(void (^)(UIColor *))handler {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
GPUImagePicture *picture = [[GPUImagePicture alloc] initWithImage:self];
GPUImageAverageColor *averageColorFilter = [GPUImageAverageColor new];
[averageColorFilter setColorAverageProcessingFinishedBlock:^(CGFloat r, CGFloat g, CGFloat b, CGFloat a, CMTime frameTime) {
UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:a];
dispatch_async(dispatch_get_main_queue(), ^{
handler(color);
});
}];
[picture addTarget:averageColorFilter];
[picture useNextFrameForImageCapture];
[picture processImage];
});
}
我还在this answer尝试了这种方法(我认为是纯粹的CPU吗?)。然后我用相同的UIImage
测试这两个方法,并注销每个方法中使用的时间。这是结果:
cpu时间:0.102402
gpu时间:0.414044
我很惊讶CPU的运行速度要快得多。那么这里的问题是什么?我是以错误的方式使用GPUImage
吗?
以上结果来自iOS模拟器。在真实设备(iPhone6s)上进行测试时,差异更大:
cpu时间:0.019034
gpu时间:0.137635
答案 0 :(得分:0)
由于在UIImage中创建GPUImagePicture需要大量的开销,因此并非颜色平均速度慢。从UIImage实例化GPUImagePicture当前需要通过Core Graphics将该图像重新渲染为纹理并将其上传到GPU。
这是一个缓慢的过程,如果你能建议我创建一次GPUImagePicture并重复使用它,或者完全避免处理UIImages(直接从相机中获取,使用原始字节等)。我一直致力于将JPEG和PNG图像直接解码为框架内的原始字节,以避免这种情况,但是还没有多少时间来完成这个。
至于颜色平均本身,它通常会明显超过原始的逐像素计算,但可能有办法改进这一点。有关此问题的详细讨论,请参阅my answer here以及随后的评论。