Optimisation d'un code de traitement d'image en ObjectiveC

SuperCed

Membre expert
Club iGen
20 Juin 2001
1 328
70
44
superced.rb38.eu
Hop, sujet intéressant pour ceux qui aiment l'optimisation. Ca reste un problème classique je pense.

En gros, j'ai un traitement équivalent sur chaque pixel d'une image.
Je me demandais s'il existait une solution simple pour optimiser un peu le code.

Genre les décalages à droite au lieu de multiplier par 255.
Ou mieux, utiliser la partie vectorielle des processeurs. Attention, c'est pour iPhone, donc il faut que ça fonctionne sur ARM.

Je sais qu'à une époque, j'avais fait des optimisations avec altivec.

Je me demande s'il existe pas aujourd'hui des solutions plus simple pour paralléliser les traitement ou faire du calcul vectoriel avec le compilo LLVM et ObjectiveC.

Voici le code, pas du tout optimisé pour le moment. Et je veux rester sur quelque chose de simple et compréhensible, et pas des créations de thread à la main ou d'assembleur.
Je suis dans une UIIMage
Bloc de code:
-(UIImage *) convertRGBLayersWithForgroundColor:(UIColor*)foregroundColor backgroundColor:(UIColor*)backgroundColor strokeColor:(UIColor*)strokeColor
{
    
    //const int ALPHA = 0;
    const int BLUE = 1;
    const int GREEN = 2;
    const int RED = 3;
    
    
    CGFloat bgRed = 0.0, bgGreen = 0.0, bgBlue = 0.0, bgAlpha =0.0;
    [backgroundColor getRed:&bgRed green:&bgGreen blue:&bgBlue alpha:&bgAlpha];
    
    CGFloat fgRed = 0.0, fgGreen = 0.0, fgBlue = 0.0, fgAlpha =0.0;
    [foregroundColor getRed:&fgRed green:&fgGreen blue:&fgBlue alpha:&fgAlpha];
    
    CGFloat stRed = 0.0, stGreen = 0.0, stBlue = 0.0, stAlpha =0.0;
    [strokeColor getRed:&stRed green:&stGreen blue:&stBlue alpha:&stAlpha];

    //Create image rectangle with current image width/height
    CGRect imageRect = CGRectMake(0, 0, self.size.width * self.scale, self.size.height * self.scale);

    int width = imageRect.size.width;
    int height = imageRect.size.height;

    // the pixels will be painted to this array
    uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));

    // clear the pixels so any transparency is preserved
    memset(pixels, 0, width * height * sizeof(uint32_t));

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // create a context with RGBA pixels
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

    // paint the bitmap to our context which will fill in the pixels array
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);

    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
            
            uint8_t originalR, originalG, originalB;
            originalR = rgbaPixel[RED];
            originalG = rgbaPixel[GREEN];
            originalB = rgbaPixel[BLUE];

            uint16_t divider = originalR + originalG + originalB;
            rgbaPixel[RED] = (uint8_t)(((originalR*stRed) + (originalG*fgRed) + (originalB*bgRed))*255/divider);
            rgbaPixel[GREEN] = (uint8_t)(((originalR*stGreen) + (originalG*fgGreen) + (originalB*bgGreen))*255/divider);
            rgbaPixel[BLUE] = (uint8_t)(((originalR*stBlue) + (originalG*fgBlue) + (originalB*bgBlue))*255/divider);
        
        }
    }

    // create a new CGImageRef from our context with the modified pixels
    CGImageRef image = CGBitmapContextCreateImage(context);

    // we're done with the context, color space, and pixels
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);

    // make a new UIImage to return
    UIImage *resultUIImage = [UIImage imageWithCGImage:image
                                                 scale:self.scale
                                           orientation:UIImageOrientationUp];

    // we're done with image now too
    CGImageRelease(image);

    return resultUIImage;
}