1

i need to improve my "drawRect" method. It´s so extremely slow. I have 10 transparent png´s which i want to merge together with different blend modes. I´ve read a post from the Apple Developer Lib and from Stackoverflow.

Now i want to know how to improve my code and the overall drawing performance. Could you please help me? Loading all these images within a for loop makes it so slow, right? How do i get the most performance?

  - (void)drawRect:(CGRect)rect {

        CGContextRef context = UIGraphicsGetCurrentContext();
        CGAffineTransform matrix =CGContextGetCTM(context);
        CGAffineTransformInvert(matrix);
        CGContextConcatCTM(context,matrix);

            CGRect contentRect;

             // load each UIImage
        for (i=0; i< [configurationArray count]; i = i + 1) {   
                    image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:nil]];

    contentRect = CGRectMake(x,y,image.size.width,image.size.height);
    CGContextSetBlendMode (context, kCGBlendModeScreen);
    CGContextSetAlpha (context, [layerData.layerAlpha floatValue]);


    CGContextDrawImage (context,contentRect, image.CGImage);

    }
}

UPDATE:

Now i´m using CALayers to put the pixel direct on the needed position. But i need different blend modes, alpha and color fills for each layer. Is there a way to avoid calling the expensive "CGContextDrawImage" method on each layer? E.g i hope its possible to just update the context for the small size of the specific layer, right? Or do i need to render the whole UIView for each context change?

I hope somebody can push me in the right direction. I just have to learn on that topic. Thanks for any help.

- (void)drawRect:(CGRect)rect {
 // load each UIImage
        for (int i=0; i< [myArray count]; i++) { 

        image = [[ImageCache sharedImageCache] imageForKey:imageName];

       CALayer* sublayer = [CALayer layer] ;

        [sublayer setPosition:CGPointMake(image.size.width/2, image.size.height/2)]; 
        [sublayer setFrame:CGRectMake(x, y, image.size.width, image.size.height)];

        CGImageRef layerImage = [image CGImage];
        [sublayer setContents:(__bridge id) layerImage];
        [sublayer setBackgroundColor:[[UIColor clearColor] CGColor]];
        [self.layer addSublayer:sublayer];

// How can i set the blend mode, color fill & alpha value without 
// calling the expensive "CGContextDrawImage" ? Possible?

}
}
Community
  • 1
  • 1
geforce
  • 2,593
  • 3
  • 28
  • 44
  • 1
    You probably shouldn't load your ten images within `-drawRect:`. Load and cache them somewhere else first. Be careful about memory usage with that many images, though. – Brad Larson Apr 05 '12 at 17:22
  • It helped me to get some better frame rates but because of the 1024x600px UIView, i hope there are more ways to improve it. What about CALayers? Any other ideas how to get more FPS? – geforce Apr 24 '12 at 10:29

1 Answers1

0

Per Brad's comment:

You probably shouldn't load your ten images within -drawRect:. Load and cache them somewhere else first. Be careful about memory usage with that many images, though.

I´ve ended with Brad's approach.

Kev
  • 118,037
  • 53
  • 300
  • 385
geforce
  • 2,593
  • 3
  • 28
  • 44