2010-04-18 4 views
0

J'applique un flou de convolution de matrice sur l'iPhone. Le code suivant convertit le UIImage fourni en tant qu'argument de la fonction de flou dans un CGImageRef, puis stocke les valeurs RGBA dans un tableau C char standard. Ensuite, les valeurs de pixels stockées dans la matrice de pixels sont convolues et stockées dans un autre tableau.Traitement d'image d'iPhone - convolution de matrice

unsigned char *results = malloc((height) * (width) * 4); 

Enfin, ces valeurs de pixels sont reconvertis augmentée en CGImageRef, converti en un UIImage, et sont revenus à la fin de la fonction avec le code suivant.

context = CGBitmapContextCreate(results, width, height, 
           bitsPerComponent, bytesPerRow, colorSpace, 
           kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGImageRef finalImage = CGBitmapContextCreateImage(context); 


UIImage *newImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; 
CGImageRelease(finalImage); 

NSLog(@"edges found"); 
free(results); 
free(pixels); 
CGColorSpaceRelease(colorSpace); 


return newImage; 

Cela fonctionne parfaitement, une fois. Ensuite, une fois l'image passée à travers le filtre, des valeurs de pixels très étranges et sans précédent représentant des valeurs de pixels d'entrée qui n'existent pas sont renvoyées. Y at-il une raison pour laquelle cela devrait fonctionner la première fois, mais pas après? En dessous est l'intégralité de la fonction.

-(UIImage*) blur:(UIImage*)imgRef { 
CGImageRef imageRef = imgRef.CGImage; 
int width = imgRef.size.width; 
int height = imgRef.size.height; 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
unsigned char *pixels = malloc((height) * (width) * 4); 
NSUInteger bytesPerPixel = 4; 
NSUInteger bytesPerRow = bytesPerPixel * (width); 
NSUInteger bitsPerComponent = 8; 
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 
              bitsPerComponent, bytesPerRow, colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
CGContextRelease(context); 


height = imgRef.size.height; 
width = imgRef.size.width; 
float matrix[] = {1,1,1,1,1,1,1,1,1}; 
float divisor = 9; 
float shift = 0; 


unsigned char *results = malloc((height) * (width) * 4); 


for(int y = 1; y < height; y++){ 
    for(int x = 1; x < width; x++){ 
     float red = 0; 
     float green = 0; 
     float blue = 0; 
     int multiplier=1; 

     if(y>0 && x>0){ 
     int index = (y-1)*width + x; 
     red = matrix[0]*multiplier*(float)pixels[4*(index-1)] + 
     matrix[1]*multiplier*(float)pixels[4*(index)] + 
     matrix[2]*multiplier*(float)pixels[4*(index+1)]; 
     green = matrix[0]*multiplier*(float)pixels[4*(index-1)+1] + 
     matrix[1]*multiplier*(float)pixels[4*(index)+1] + 
     matrix[2]*multiplier*(float)pixels[4*(index+1)+1]; 
     blue = matrix[0]*multiplier*(float)pixels[4*(index-1)+2] + 
     matrix[1]*multiplier*(float)pixels[4*(index)+2] + 
     matrix[2]*multiplier*(float)pixels[4*(index+1)+2]; 

     index = (y)*width + x; 

     red = red+ matrix[3]*multiplier*(float)pixels[4*(index-1)] + 
     matrix[4]*multiplier*(float)pixels[4*(index)] + 
     matrix[5]*multiplier*(float)pixels[4*(index+1)]; 
     green = green + matrix[3]*multiplier*(float)pixels[4*(index-1)+1] + 
     matrix[4]*multiplier*(float)pixels[4*(index)+1] + 
     matrix[5]*multiplier*(float)pixels[4*(index+1)+1]; 
     blue = blue + matrix[3]*multiplier*(float)pixels[4*(index-1)+2] + 
     matrix[4]*multiplier*(float)pixels[4*(index)+2] + 
     matrix[5]*multiplier*(float)pixels[4*(index+1)+2]; 


     index = (y+1)*width + x; 
     red = red+ matrix[6]*multiplier*(float)pixels[4*(index-1)] + 
     matrix[7]*multiplier*(float)pixels[4*(index)] + 
     matrix[8]*multiplier*(float)pixels[4*(index+1)]; 
     green = green + matrix[6]*multiplier*(float)pixels[4*(index-1)+1] + 
     matrix[7]*multiplier*(float)pixels[4*(index)+1] + 
     matrix[8]*multiplier*(float)pixels[4*(index+1)+1]; 
     blue = blue + matrix[6]*multiplier*(float)pixels[4*(index-1)+2] + 
     matrix[7]*multiplier*(float)pixels[4*(index)+2] + 
     matrix[8]*multiplier*(float)pixels[4*(index+1)+2]; 

     red = red/divisor+shift; 
     green = green/divisor+shift; 
     blue = blue/divisor+shift; 

     if(red<0){ 
      red=0; 
     } 
     if(green<0){ 
      green=0; 
     } 
     if(blue<0){ 
      blue=0; 
     } 

     if(red>255){ 
      red=255; 
     } 
     if(green>255){ 
      green=255; 
     } 
     if(blue>255){ 
      blue=255; 
     } 

     int realPos = 4*(y*imgRef.size.width + x); 

     results[realPos] = red; 
     results[realPos + 1] = green; 
     results[realPos + 2] = blue; 
     results[realPos + 3] = 1; 

      }else { 
     int realPos = 4*((y)*(imgRef.size.width) + (x)); 
     results[realPos] = 0; 
     results[realPos + 1] = 0; 
     results[realPos + 2] = 0; 
     results[realPos + 3] = 1; 
     } 

    } 
} 

context = CGBitmapContextCreate(results, width, height, 
           bitsPerComponent, bytesPerRow, colorSpace, 
           kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGImageRef finalImage = CGBitmapContextCreateImage(context); 


UIImage *newImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; 
CGImageRelease(finalImage); 

free(results); 
free(pixels); 
CGColorSpaceRelease(colorSpace); 


return newImage;} 

MERCI !!!

Répondre

1

Le problème était que je supposais la valeur alpha, nécessaire pour le calculer comme les valeurs RVB.

+0

bonjour pouvez-vous s'il vous plaît mettre à jour votre code exemple ici .. Thx –

+0

désolé je n'ai aucune idée d'où ce code est plus. Prenez simplement le code ci-dessus et calculez les valeurs alpha juste au moment où les valeurs RVB sont calculées. – James