A.
使用vImage API进行模糊
iOS5.0中新增了vImage API可以使用,它属于Accelerate.Framework,所以如果你要使用它要在工程中加入这个Framework。模糊算法使用的是vImageBoxConvolve_ARGB8888这个函数。
1 - (UIImage *)blurredImageWithRadius:(CGFloat)radius iterations:(NSUInteger)iterations tintColor:(UIColor *)tintColor 2 3 { 4 5 //image must be nonzero size 6 7 if (floorf(self.size.width) * floorf(self.size.height) <= 0.0f) return self; 8 9 //boxsize must be an odd integer 10 11 uint32_t boxSize = (uint32_t)(radius * self.scale); 12 13 if (boxSize % 2 == 0) boxSize ++; 14 15 //create image buffers 16 17 CGImageRef imageRef = self.CGImage; 18 19 vImage_Buffer buffer1, buffer2; 20 21 buffer1.width = buffer2.width = CGImageGetWidth(imageRef); 22 23 buffer1.height = buffer2.height = CGImageGetHeight(imageRef); 24 25 buffer1.rowBytes = buffer2.rowBytes = CGImageGetBytesPerRow(imageRef); 26 27 size_t bytes = buffer1.rowBytes * buffer1.height; 28 29 buffer1.data = malloc(bytes); 30 31 buffer2.data = malloc(bytes); 32 33 //create temp buffer 34 35 void *tempBuffer = malloc((size_t)vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, NULL, 0, 0, boxSize, boxSize, 36 37 NULL, kvImageEdgeExtend + kvImageGetTempBufferSize)); 38 39 //copy image data 40 41 CFDataRef dataSource = CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); 42 43 memcpy(buffer1.data, CFDataGetBytePtr(dataSource), bytes); 44 45 CFRelease(dataSource); 46 47 for (NSUInteger i = 0; i < iterations; i++) 48 49 { 50 51 //perform blur 52 53 vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, tempBuffer, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend); 54 55 //swap buffers 56 57 void *temp = buffer1.data; 58 59 buffer1.data = buffer2.data; 60 61 buffer2.data = temp; 62 63 } 64 65 //free buffers 66 67 free(buffer2.data); 68 69 free(tempBuffer); 70 71 //create image context from buffer 72 73 CGContextRef ctx = CGBitmapContextCreate(buffer1.data, buffer1.width, buffer1.height, 74 75 8, buffer1.rowBytes, CGImageGetColorSpace(imageRef), 76 77 CGImageGetBitmapInfo(imageRef)); 78 79 //apply tint 80 81 if (tintColor && CGColorGetAlpha(tintColor.CGColor) > 0.0f) 82 83 { 84 85 CGContextSetFillColorWithColor(ctx, [tintColor colorWithAlphaComponent:0.25].CGColor); 86 87 CGContextSetBlendMode(ctx, kCGBlendModePlusLighter); 88 89 CGContextFillRect(ctx, CGRectMake(0, 0, buffer1.width, buffer1.height)); 90 91 } 92 93 //create image from context 94 95 imageRef = CGBitmapContextCreateImage(ctx); 96 97 UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; 98 99 CGImageRelease(imageRef); 100 101 CGContextRelease(ctx); 102 103 free(buffer1.data); 104 105 return image; 106 107 }