IOS中模糊效果实现的几种方法(毛玻璃)(转载)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了IOS中模糊效果实现的几种方法(毛玻璃)(转载),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含17499字,纯文字阅读大概需要25分钟。
内容图文
在手机里面经常可以看到模糊效果,比如说控制中心。
那么这种效果怎么去实现的呢,一般有一下几种办法。
1.CoreImage
2.vImage(UIImageView+Effective)
3.GPUImage
4.UIVisualEfftiveView
下面来说说这几种方法的使用方法:
一、CoreImage
1 - (void)test1 { 2//原始图片 3 UIImage *originImage = [UIImage imageNamed:@"bg1.jpg"]; 4//创建上下文 5 CIContext *context = [CIContext contextWithOptions:nil]; 6//将原始图片转换成CIImage 7 CIImage *inputImage = [CIImage imageWithCGImage:originImage.CGImage]; 8//创建滤镜 9 CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"]; 10//设置滤镜的属性11 [filter setValue:inputImage forKey:kCIInputImageKey]; 12//模糊半径13 [filter setValue:@10.f forKey:@"inputRadius"]; 14//输出图片15 CIImage *outputImage = [filter valueForKey:kCIOutputImageKey]; 16//转换成CGImage17 CGImageRef ref = [context createCGImage:outputImage fromRect:[outputImage extent]]; 18//转换成UIImage19 UIImage *newImage = [UIImage imageWithCGImage:ref]; 20//释放21 CGImageRelease(ref); 22 }
二、vImage
vImage是苹果推出的库,是在Accelerate.framework中
Accelerate这个framework主要是用来做数字信号处理、图像处理相关的向量、矩阵运算的库。我们可以认为我们的图像都是由向量或者矩阵数据构成的,Accelerate里既然提供了高效的数学运算API,自然就能方便我们对图像做各种各样的处理。
基于vImage我们可以根据图像的处理原理直接做模糊效果,或者使用现有的工具。UIImage+ImageEffects是个很好的图像处理库,看名字也知道是对UIImage做的分类扩展。这个工具被广泛地使用着。
1 @import UIKit; 2 3 @interface UIImage (ImageEffects) 4 5 #pragma mark - Blur Image 6 7/** 8 * Get blured image. 9 * 10 * @return Blured image. 11*/12 - (UIImage *)blurImage; 1314/** 15 * Get the blured image masked by another image. 16 * 17 * @param maskImage Image used for mask. 18 * 19 * @return the Blured image. 20*/21 - (UIImage *)blurImageWithMask:(UIImage *)maskImage; 2223/** 24 * Get blured image and you can set the blur radius. 25 * 26 * @param radius Blur radius. 27 * 28 * @return Blured image. 29*/30 - (UIImage *)blurImageWithRadius:(CGFloat)radius; 3132/** 33 * Get blured image at specified frame. 34 * 35 * @param frame The specified frame that you use to blur. 36 * 37 * @return Blured image. 38*/39 - (UIImage *)blurImageAtFrame:(CGRect)frame; 4041#pragma mark - Grayscale Image 4243/** 44 * Get grayScale image. 45 * 46 * @return GrayScaled image. 47*/48 - (UIImage *)grayScale; 4950#pragma mark - Some Useful Method 5152/** 53 * Scale image with fixed width. 54 * 55 * @param width The fixed width you give. 56 * 57 * @return Scaled image. 58*/59 - (UIImage *)scaleWithFixedWidth:(CGFloat)width; 6061/** 62 * Scale image with fixed height. 63 * 64 * @param height The fixed height you give. 65 * 66 * @return Scaled image. 67*/68 - (UIImage *)scaleWithFixedHeight:(CGFloat)height; 6970/** 71 * Get the image average color. 72 * 73 * @return Average color from the image. 74*/75 - (UIColor *)averageColor; 7677/** 78 * Get cropped image at specified frame. 79 * 80 * @param frame The specified frame that you use to crop. 81 * 82 * @return Cropped image 83*/84 - (UIImage *)croppedImageAtFrame:(CGRect)frame; 8586@end
1 #import " UIImage+ImageEffects.h " 2 #import <float.h> 3@import Accelerate; 4 5@implementation UIImage (ImageEffects) 6 7 8 - (UIImage *)applyLightEffect{ 9 10 UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3]; 11return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 12} 13 14 15 - (UIImage *)applyExtraLightEffect { 16 17 UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82]; 18return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 19} 20 21 22 - (UIImage *)applyDarkEffect { 23 24 UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73]; 25return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 26} 27 28 29 - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor { 30 31const CGFloat EffectColorAlpha = 0.6; 32 UIColor *effectColor = tintColor; 33int componentCount = (int)CGColorGetNumberOfComponents(tintColor.CGColor); 34 35if (componentCount == 2) { 36 37 CGFloat b; 38if ([tintColor getWhite:&b alpha:NULL]) { 39 40 effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha]; 41 } 42 43 } else { 44 45 CGFloat r, g, b; 46if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) { 47 48 effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha]; 49 } 50 } 51 52return [self applyBlurWithRadius:20 tintColor:effectColor saturationDeltaFactor:1.4 maskImage:nil]; 53} 54 55 - (UIImage *)blurImage { 56 57return [self applyBlurWithRadius:20 58 tintColor:[UIColor colorWithWhite:0 alpha:0.0] 59 saturationDeltaFactor:1.4 60 maskImage:nil]; 61} 62 63 - (UIImage *)blurImageWithRadius:(CGFloat)radius { 64 65return [self applyBlurWithRadius:radius 66 tintColor:[UIColor colorWithWhite:0 alpha:0.0] 67 saturationDeltaFactor:1.4 68 maskImage:nil]; 69} 70 71 - (UIImage *)blurImageWithMask:(UIImage *)maskImage { 72 73return [self applyBlurWithRadius:20 74 tintColor:[UIColor colorWithWhite:0 alpha:0.0] 75 saturationDeltaFactor:1.4 76 maskImage:maskImage]; 77} 78 79 - (UIImage *)blurImageAtFrame:(CGRect)frame { 80 81return [self applyBlurWithRadius:20 82 tintColor:[UIColor colorWithWhite:0 alpha:0.0] 83 saturationDeltaFactor:1.4 84 maskImage:nil 85 atFrame:frame]; 86} 87 88 - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage { 89 90// Check pre-conditions. 91if (self.size.width < 1 || self.size.height < 1) { 92 93 NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self); 94return nil; 95 } 96 97if (!self.CGImage) { 98 99 NSLog (@"*** error: image must be backed by a CGImage: %@", self); 100return nil; 101 } 102103if (maskImage && !maskImage.CGImage) { 104105 NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage); 106return nil; 107 } 108109 CGRect imageRect = { CGPointZero, self.size }; 110 UIImage *effectImage = self; 111112 BOOL hasBlur = blurRadius > __FLT_EPSILON__; 113 BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; 114if (hasBlur || hasSaturationChange) { 115116 UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 117 CGContextRef effectInContext = UIGraphicsGetCurrentContext(); 118 CGContextScaleCTM(effectInContext, 1.0, -1.0); 119 CGContextTranslateCTM(effectInContext, 0, -self.size.height); 120 CGContextDrawImage(effectInContext, imageRect, self.CGImage); 121122 vImage_Buffer effectInBuffer; 123 effectInBuffer.data = CGBitmapContextGetData(effectInContext); 124 effectInBuffer.width = CGBitmapContextGetWidth(effectInContext); 125 effectInBuffer.height = CGBitmapContextGetHeight(effectInContext); 126 effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext); 127128 UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 129 CGContextRef effectOutContext = UIGraphicsGetCurrentContext(); 130 vImage_Buffer effectOutBuffer; 131 effectOutBuffer.data = CGBitmapContextGetData(effectOutContext); 132 effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext); 133 effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext); 134 effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext); 135136if (hasBlur) { 137138// A description of how to compute the box kernel width from the Gaussian 139// radius (aka standard deviation) appears in the SVG spec: 140//http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement 141//142// For larger values of ‘s‘ (s >= 2.0), an approximation can be used: Three 143// successive box-blurs build a piece-wise quadratic convolution kernel, which 144// approximates the Gaussian kernel to within roughly 3%. 145//146// let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) 147//148// ... if d is odd, use three box-blurs of size ‘d‘, centered on the output pixel. 149//150 CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale]; 151 NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5); 152if (radius % 2 != 1) { 153154 radius += 1; // force radius to be odd so that the three box-blur methodology works.155 } 156157 vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend); 158 vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend); 159 vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend); 160 } 161162 BOOL effectImageBuffersAreSwapped = NO; 163if (hasSaturationChange) { 164165 CGFloat s = saturationDeltaFactor; 166 CGFloat floatingPointSaturationMatrix[] = { 1670.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 1680.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 1690.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 1700, 0, 0, 1, 171 }; 172const int32_t divisor = 256; 173 NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]); 174 int16_t saturationMatrix[matrixSize]; 175176for (NSUInteger i = 0; i < matrixSize; ++i) { 177178 saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor); 179 } 180181if (hasBlur) { 182183 vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 184 effectImageBuffersAreSwapped = YES; 185186 } else { 187188 vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 189 } 190 } 191192if (!effectImageBuffersAreSwapped) { 193194 effectImage = UIGraphicsGetImageFromCurrentImageContext(); 195 } 196197 UIGraphicsEndImageContext(); 198199if (effectImageBuffersAreSwapped) { 200201 effectImage = UIGraphicsGetImageFromCurrentImageContext(); 202 } 203204 UIGraphicsEndImageContext(); 205 } 206207// Set up output context.208 UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 209 CGContextRef outputContext = UIGraphicsGetCurrentContext(); 210 CGContextScaleCTM(outputContext, 1.0, -1.0); 211 CGContextTranslateCTM(outputContext, 0, -self.size.height); 212213// Draw base image.214 CGContextDrawImage(outputContext, imageRect, self.CGImage); 215216// Draw effect image.217if (hasBlur) { 218219 CGContextSaveGState(outputContext); 220221if (maskImage) { 222223 CGContextClipToMask(outputContext, imageRect, maskImage.CGImage); 224 } 225226 CGContextDrawImage(outputContext, imageRect, effectImage.CGImage); 227 CGContextRestoreGState(outputContext); 228 } 229230// Add in color tint.231if (tintColor) { 232233 CGContextSaveGState(outputContext); 234 CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); 235 CGContextFillRect(outputContext, imageRect); 236 CGContextRestoreGState(outputContext); 237 } 238239// Output image is ready.240 UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 241 UIGraphicsEndImageContext(); 242243return outputImage; 244} 245246 - (UIImage *)grayScale { 247248int width = self.size.width; 249int height = self.size.height; 250251 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 252253 CGContextRef context = CGBitmapContextCreate(nil, 254 width, 255 height, 2568, // bits per component2570, 258 colorSpace, 259 kCGBitmapByteOrderDefault); 260261 CGColorSpaceRelease(colorSpace); 262263if (context == NULL) { 264265return nil; 266 } 267268 CGContextDrawImage(context, 269 CGRectMake(0, 0, width, height), self.CGImage); 270 CGImageRef image = CGBitmapContextCreateImage(context); 271 UIImage *grayImage = [UIImage imageWithCGImage:image]; 272 CFRelease(image); 273 CGContextRelease(context); 274275return grayImage; 276} 277278 - (UIImage *)scaleWithFixedWidth:(CGFloat)width { 279280float newHeight = self.size.height * (width / self.size.width); 281 CGSize size = CGSizeMake(width, newHeight); 282 UIGraphicsBeginImageContextWithOptions(size, NO, 0); 283284 CGContextRef context = UIGraphicsGetCurrentContext(); 285286 CGContextTranslateCTM(context, 0.0, size.height); 287 CGContextScaleCTM(context, 1.0, -1.0); 288289 CGContextSetBlendMode(context, kCGBlendModeCopy); 290 CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage); 291292 UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext(); 293294 UIGraphicsEndImageContext(); 295296return imageOut; 297} 298299 - (UIImage *)scaleWithFixedHeight:(CGFloat)height { 300301float newWidth = self.size.width * (height / self.size.height); 302 CGSize size = CGSizeMake(newWidth, height); 303304 UIGraphicsBeginImageContextWithOptions(size, NO, 0); 305306 CGContextRef context = UIGraphicsGetCurrentContext(); 307308 CGContextTranslateCTM(context, 0.0, size.height); 309 CGContextScaleCTM(context, 1.0, -1.0); 310311 CGContextSetBlendMode(context, kCGBlendModeCopy); 312 CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage); 313314 UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext(); 315316 UIGraphicsEndImageContext(); 317318return imageOut; 319} 320321 - (UIColor *)averageColor { 322323 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 324 unsigned char rgba[4]; 325 CGContextRef context = CGBitmapContextCreate(rgba, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 326327 CGContextDrawImage(context, CGRectMake(0, 0, 1, 1), self.CGImage); 328 CGColorSpaceRelease(colorSpace); 329 CGContextRelease(context); 330331if(rgba[3] > 0) { 332 CGFloat alpha = ((CGFloat)rgba[3])/255.0; 333 CGFloat multiplier = alpha/255.0; 334return [UIColor colorWithRed:((CGFloat)rgba[0])*multiplier 335 green:((CGFloat)rgba[1])*multiplier 336 blue:((CGFloat)rgba[2])*multiplier 337 alpha:alpha]; 338 } 339else { 340return [UIColor colorWithRed:((CGFloat)rgba[0])/255.0341 green:((CGFloat)rgba[1])/255.0342 blue:((CGFloat)rgba[2])/255.0343 alpha:((CGFloat)rgba[3])/255.0]; 344 } 345} 346347 - (UIImage *)croppedImageAtFrame:(CGRect)frame { 348349 frame = CGRectMake(frame.origin.x * self.scale, 350 frame.origin.y * self.scale, 351 frame.size.width * self.scale, 352 frame.size.height * self.scale); 353354 CGImageRef sourceImageRef = [self CGImage]; 355 CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, frame); 356 UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:[self scale] orientation:[self imageOrientation]]; 357 CGImageRelease(newImageRef); 358return newImage; 359} 360361 - (UIImage *)addImageToImage:(UIImage *)img atRect:(CGRect)cropRect { 362363 CGSize size = CGSizeMake(self.size.width, self.size.height); 364 UIGraphicsBeginImageContextWithOptions(size, NO, self.scale); 365366 CGPoint pointImg1 = CGPointMake(0,0); 367 [self drawAtPoint:pointImg1]; 368369 CGPoint pointImg2 = cropRect.origin; 370 [img drawAtPoint: pointImg2]; 371372 UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); 373 UIGraphicsEndImageContext(); 374375return result; 376} 377378 - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius 379 tintColor:(UIColor *)tintColor 380 saturationDeltaFactor:(CGFloat)saturationDeltaFactor 381 maskImage:(UIImage *)maskImage 382 atFrame:(CGRect)frame 383{ 384 UIImage *blurredFrame =385 [[self croppedImageAtFrame:frame] applyBlurWithRadius:blurRadius 386 tintColor:tintColor 387 saturationDeltaFactor:saturationDeltaFactor 388 maskImage:maskImage]; 389390return [self addImageToImage:blurredFrame atRect:frame]; 391} 392393@end
使用方法很简单,如下所示:
1 - (void)test2 { 2//原始图片 3 UIImage *originImage = [UIImage imageNamed:@"bg1.jpg"]; 4//整体模糊 5 UIImage *newImage1 = [originImage blurImage]; 6//局部模糊 7 UIImage *newImage2 = [originImage blurImageAtFrame:CGRectMake(0, 100, 320, 200)]; 8//设置模糊半径 9 UIImage *newImage3 = [originImage blurImageWithRadius:10.f]; 10 }
三、GPUImage
GPUImage框架如何导入,我之前的文章有说过了(戳我)。
使用起来也是很简单的:
1 - (void)test3 { 2//创建滤镜 3 GPUImageGaussianBlurFilter *filter = [[GPUImageGaussianBlurFilter alloc] init]; 4//设置模糊半径 5 filter.blurRadiusInPixels = 10.f; 6//原始图片 7 UIImage *image = [UIImage imageNamed:@"bg1.jpg"]; 8//模糊后的图片 9 UIImage *newImage = [filter imageByFilteringImage:image]; 10 }
四、UIVisualEffectView
注意:这个只能在IOS8以上才能使用,并且可以动态的模糊哟~
效果图:
- (void)viewDidLoad { [super viewDidLoad]; //初始化scrollView self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg1.jpg"]]; [self.scrollView addSubview:imgView]; self.scrollView.contentSize = imgView.image.size; self.scrollView.bounces = NO; [self.view addSubview:self.scrollView]; //使用UIVisualEffectiveView,添加模糊效果 UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]]; //设置frame effectView.frame = CGRectMake(0, 100, SCREEN_WIDTH, 200); //添加到view上,注意一定要添加在scrollView之上 [self.view addSubview:effectView]; //在effective上添加子view,使其子view也具有模糊效果 //初始化一个label UILabel *txt = [[UILabel alloc] initWithFrame:effectView.bounds]; txt.text = @"模糊效果"; txt.textAlignment = NSTextAlignmentCenter; txt.font = [UIFont systemFontOfSize:50.f]; //创建子模糊view UIVisualEffectView *subView = [[UIVisualEffectView alloc] initWithEffect:[UIVibrancyEffect effectForBlurEffect:(UIBlurEffect *)effectView.effect]]; //设置frame subView.frame = effectView.bounds; //添加至contentView中去 [effectView.contentView addSubview:subView]; [subView.contentView addSubview:txt]; }
原文:http://www.cnblogs.com/xinSky/p/5537076.html
内容总结
以上是互联网集市为您收集整理的IOS中模糊效果实现的几种方法(毛玻璃)(转载)全部内容,希望文章能够帮你解决IOS中模糊效果实现的几种方法(毛玻璃)(转载)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。