2010-04-18 87 views
0

我正在iPhone上实现矩阵卷积模糊。以下代码将作为blur函数参数提供的UIImage转换为CGImageRef,然后将RGBA值存储在标准C char数组中。iPhone图像处理 - 矩阵卷积

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); 

然后,存储在像素数组中的像素值被卷积,并存储在另一个数组中。

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

最后,这些扩充的像素值变回成一个CGImageRef,转换为一个UIImage,并且在用下面的代码的功能的端部的返回。

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; 

这个工作完美,一次。然后,一旦图像再次通过滤波器,就会返回非常奇怪的前所未有的表示不存在的输入像素值的像素值。有什么理由为什么这应该是第一次,但之后没有?下面是整个功能。

-(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;} 

谢谢!!!

回答

1

问题是我假设的alpha值,需要计算它像RGB值。

+0

您好,请您在此更新您的示例代码。Thx – 2011-06-18 06:47:16

+0

抱歉,我不知道此代码在哪里了。只需从上面获取代码,并计算出alpha值,就像计算RGB值一样。 – James 2011-06-18 14:08:11