我正在iPhone上实现矩阵卷积模糊。以下代码将作为blur函数的参数提供的UIImage转换为CGImageRef,然后将RGBA值存储在标准C char数组中。
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;
一次完美无缺。然后,一旦图像再次通过滤波器,则返回表示不存在的输入像素值的非常奇怪的,前所未有的像素值。有没有理由为什么这应该第一次工作,但之后不是? Beneath是整个功能。
-(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;}
感谢!!!
答案 0 :(得分:1)
问题是我正在假设alpha值,需要像RGB值那样计算它。