2009-08-30 96 views
1

我正在尝试对像素进行迭代,以在不使用OpenGL的情况下更改UIImage的RGBA值。我尝试使用下面的代码测试迭代性能,但非常不满。似乎我每秒只能获得几千次迭代。而对于数十万像素的UIImage来说,这将取代TOO LONG ...任何人对于如何提高性能或这些操作通常需要多长时间都有任何建议?Core Graphics在iPhone上的PIXEL迭代性能很差吗?

-(UIImage*)modifyPixels:(UIImage*)originalImage 
{ 
    NSData* pixelData = (NSData*)CGDataProviderCopyData(CGImageGetDataProvider(originalImage.CGImage)); 
    void* pixelBytes = [pixelData bytes]; 

    // Take away the red pixel, assuming 32-bit RGBA 
    for(int i = 0; i < [pixelData length]; i += 4) { 
     NSLog(@" %ith iteration (%i/%i/%i/%i)", i, pixelData[i], pixelData[i+1], pixelData[i+2], pixelData[i+3]); 
    } 

    //NSData* newPixelData = [NSData dataWithBytes:pixelBytes length:[pixelData length]]; 
    //UIImage* newImage = [UIImage imageWithData:newPixelData]; 

    return originalImage;  
} 
+0

请注意,您在此处泄漏pixelData。包含“复制”的核心基础(和通过扩展的CG)函数会返回一个保留对象。 – 2009-08-30 02:55:33

+0

好的,谢谢你。 – RexOnRoids 2009-08-30 03:17:42

回答

4

您的NSLog语句将显着减慢图像迭代过程。一个好的测试是反转图像,而不是注销像素数据。同时计算每次迭代的数据长度也会减慢速度。缓存一个局部变量的长度并使用它。

+0

同意。 NSLog()可能会非常慢。 – 2009-08-30 02:52:17

+0

谢谢。这帮助了很多! – RexOnRoids 2009-08-30 03:02:23

5

不要在循环中调用[pixelData length]。编译器无法知道此消息的结果是否为常量,因此它会调用该方法。

+0

这是一个非常好的提示;我见过有经验的开发者忽略了这一点。 – rpetrich 2009-08-30 03:44:24

0

您的代码的基本问题是,您将像素视为4字节元素。作为第一步你需要做的是读一个4字节的块作为1个字。使用uint32_t类型,然后每次读取1个字到寄存器中。这会导致内存读取操作减少4倍,然后将每个像素存储在1 32位寄存器中。每个字包含RGBA,每个组件占用32位字的8位。然后您需要使用位移操作来操作组件。这是一篇博客文章,向您展示如何使用iOS原生BGRA格式像素pixel_binary_layout。无论您的像素逻辑如何,您都需要将结果写出来,然后检查这些结果以确保一切按预期工作。在ARM芯片上读写整个单词的速度要快于读取字节数的4倍,所以你应该看到一个很大的改进。