-1

My question is simple, I have the following code, it creates an array of Hues got from a function that returns the UIColor of an image (this is not important, just context). So, I need to create this array as fast as possible, this test runs with only a 5x5 pixels image and it takes about 3sec, I want to be able to run a 50x50 pixels image (at least) in about 2 secods (tops), any ideas?

- (void)createArrayOfHues: (UIImage *)imageScaned{
    if (imageScaned != nil) {

        NSLog(@"Creating Array...");

        UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
        img.contentMode = UIViewContentModeScaleToFill;
        img.image = imageScaned;
        img.contentMode = UIViewContentModeRedraw;
        img.hidden = YES;



        int i = 0;
        CGFloat hue = 0;
        CGFloat sat = 0;
        CGFloat brit = 0;
        CGFloat alph = 0;
        CGFloat hue2 = 0;
        CGFloat sat2 = 0;
        CGFloat brit2 = 0;
        CGFloat alph2 = 0;

        [_colorsArray removeAllObjects];
        [_satForHue removeAllObjects];
        [_britForHue removeAllObjects];
        [_alphForHue removeAllObjects];

        _colorsArray = [[NSMutableArray alloc] initWithCapacity:(25)];
        _satForHue = [[NSMutableArray alloc] initWithCapacity:(25)];
        _britForHue = [[NSMutableArray alloc] initWithCapacity:(25)];
        _alphForHue = [[NSMutableArray alloc] initWithCapacity:(25)];

        while (i<25) {


            for (int y=1; y <= 5; y++){
                for (int x = 1; x <= 2.5; x++){

                    if (x != (5-x)){
                        UIColor *color = [self colorMatch:imageScaned :x :y];
                        UIColor *color2 = [self colorMatch:imageScaned :(5-x) :y];


                        if([color getHue:&hue saturation:&sat brightness:&brit alpha:&alph] && [color2 getHue:&hue2 saturation:&sat2 brightness:&brit2 alpha:&alph2]){

                            NSNumber *hueId = [NSNumber numberWithFloat:(float)hue];
                            NSNumber *satId = [NSNumber numberWithFloat:(float)sat];
                            NSNumber *britId = [NSNumber numberWithFloat:(float)brit];
                            NSNumber *alphId = [NSNumber numberWithFloat:(float)alph];
                            NSNumber *hueId2 = [NSNumber numberWithFloat:(float)hue2];
                            NSNumber *satId2 = [NSNumber numberWithFloat:(float)sat2];
                            NSNumber *britId2 = [NSNumber numberWithFloat:(float)brit2];
                            NSNumber *alphId2 = [NSNumber numberWithFloat:(float)alph2];


                            [_colorsArray insertObject:hueId atIndex:i];
                            [_satForHue insertObject:satId atIndex:i];
                            [_britForHue insertObject:britId atIndex:i];
                            [_alphForHue insertObject:alphId atIndex:i];

                            [_colorsArray insertObject:hueId2 atIndex:(i+1)];
                            [_satForHue insertObject:satId2 atIndex:(i+1)];
                            [_britForHue insertObject:britId2 atIndex:(i+1)];
                            [_alphForHue insertObject:alphId2 atIndex:(i+1)];


                        }
                        NSLog(@"color inserted at %i with x: %i and y: %i" , i , x, y);
                        i++;
                    }else {

                        UIColor *color = [self colorMatch:imageScaned :x :y];
                        if([color getHue:&hue saturation:&sat brightness:&brit alpha:&alph]){
                            NSNumber *hueId = [NSNumber numberWithFloat:(float)hue];
                            NSNumber *satId = [NSNumber numberWithFloat:(float)sat];
                            NSNumber *britId = [NSNumber numberWithFloat:(float)brit];
                            NSNumber *alphId = [NSNumber numberWithFloat:(float)alph];
                            [_colorsArray insertObject:hueId atIndex:i];
                            [_satForHue insertObject:satId atIndex:i];
                            [_britForHue insertObject:britId atIndex:i];
                            [_alphForHue insertObject:alphId atIndex:i];

                        }

                    }
                }

            }
        }
        NSLog(@"Returns the array");

    }else{
        NSLog(@"Returns nothing");
    }
}

The code for colorMatch:

- (UIColor *) colorMatch: (UIImage *)image :(int) x :(int) y {
isBlackColored = NO;
if (image == nil){
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    BOOL customColor = [defaults boolForKey:@"custom_color"];



    if (customColor){
        float red = [defaults floatForKey:@"custom_color_slider_red"];
        float green = [defaults floatForKey:@"custom_color_slider_green"];
        float blue = [defaults floatForKey:@"custom_color_slider_blue"];
        return [UIColor colorWithRed:red green:green blue:blue alpha:1];

    }else
        isDefaultS = YES;
}
else{
        CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
        const UInt8* data = CFDataGetBytePtr(pixelData);

        int pixelInfo = ((image.size.width  * y) + x ) * 4; 

        UInt8 red = data[pixelInfo];         
        UInt8 green = data[(pixelInfo + 1)]; 
        UInt8 blue = data[pixelInfo + 2];    
        UInt8 alpha = data[pixelInfo + 3];   
        CFRelease(pixelData);
        float redC = red/255.0f;
        float greenC = green/255.0f;
        float blueC = blue/255.0f;

        UIColor* color = [UIColor colorWithRed:redC green:greenC blue:blueC alpha:alpha/255.0f];


    return color;

    }

return nil;
}
4

1 回答 1

2

我认为您的主要性能瓶颈不是 NSMutableArray 实例的初始化,而是索引图像的方式:

UIColor *color = [self colorMatch:imageScaned :x :y];

我猜这个方法将 UIImage 转换为 CGImageRef,复制它的数据,索引它,然后销毁/释放这些临时对象,或者类似的东西 -对于每个像素...... 你应该重构这个代码来获取图像缓冲区只有一次,然后像普通的 C 指针/数组一样使用它。如果这不能解决您的性能问题,您应该进行一些分析。

于 2013-09-21T15:41:29.153 回答