iOS通知栏磨砂透明背景的代码实现(高斯模糊)
2014-03-11 11:05
1146 查看
方法一.使用UIToolBar可以支持iOS7之后的高斯模糊效果
利用UIToolbar来实现是最简单的毛玻璃效果。需要什么控件自行添加到toolbar上就OK。
初始化UIToolbar,设置toolbar样式为UIBarStyleBlackTranslucent或者UIBarStyleBlackOpaque 即可。修改bartintcolor的RGB值 可修改毛玻璃色调效果。
通过本人亲身尝试,其实UIToolBar,UINavigationBar,UITabbar在IOS7上都会有高斯效果,当然,有些机型不支持(后面会总结),然后他们的表现都是一模一样的,细微的差别就是各个控件上的边框多了一些圆角,横线,但是实现高斯效果的类都是用同一个。具体是什么类,可以去研究一下,这里不深入介绍那个类,只讲怎么使用
高斯效果有系统提供的有两种效果,白色底和黑色底。具体通过设置UIBarStyle属性去设置,有UIBarStyleDefault和UIBarStyleBlack,这两种效果对比起来,Black的效果最佳,所以现在在系统本身,都是用Black样式。
但是有人想,如果只有这两种样式,能不能通过修改一些属性去改变样式呢。下面尝试了几种方法
1.alpha值
通过修改alpha值,发现,如果alpha值不为1,那么就没有高斯效果,假如你对UIToolbar进行alpha值渐变,你会发现只有等到为1的时候才会有效果,所以alpha值不能修改,会导致高斯模糊失效
2.mask
由于UIToolbar只有是矩形的样式,我们可以通过mask属性对图像进行处理,通过根据我们自定的图形,mask对应的图形,但是,如果你使用了mask,那么很不好意思,高斯模糊没有了。
3.tintColor
设置了没效果
4.barTintColor
这个是设置bar 背景颜色,设置之后,发现有效果,但是效果不明显,有兴趣可以设置一下
至于其他属性,有兴趣可以去设置一下,我是没找到其他属性了
根据好几天的接触,发现了IOS7的高斯模糊的一个特点,由于系统是支持实时更新,这部分运算明显是有效率问题的,但是我们发现,系统的好像感觉不到效率问题。通过观察,发现,如果背景图片颜色比较单一,简单,高斯模糊效果很一般,有时候就只是简单的alpha透明过去,如果背景颜色块比较明显,那么高斯效果就很清晰,可见苹果对这个的处理还是做了优化,而不是每时每刻都在刷新界面,不然效率肯定提不上来。
机型限制,目前只支持IOS7系统,4s和以上的机型,touch5,ipad上屏幕较大,支持ipad4以上
示例代码:
@property (weak, nonatomic) IBOutlet UIToolbar *bottomTabsBarBlurBgView;
@property (weak, nonatomic) IBOutlet SingleSelectTabsView *bottomTabsBar;
- (void)awakeFromNib
{
[super awakeFromNib];
self.bottomTabsBarBlurBgView.barStyle = UIBarStyleBlack;
self.bottomTabsBarBlurBgView.hidden = IS_AT_LEAST_IOS7 ? NO : YES;
self.bottomTabsBar.alpha = IS_AT_LEAST_IOS7 ? 1 : 0.95;
self.bottomTabsBar.backgroundColor = IS_AT_LEAST_IOS7 ? UIColorFromRGB(255, 255, 255, 0) : UIColorFromRGB(25, 25, 25, 1);
}
方法二.通过图片处理+实时刷新的方法实现(但是有性能问题)
(1).工程中添加Accelerate.framework。
(2).添加Category文件UIImage+ImageEffects.h/UIImage+ImageEffects.m.
(3).使用Sample代码(图片可以通过截屏背景得到,从而有磨砂透明的盖层效果)。————>苹果官方Demo<————
利用UIToolbar来实现是最简单的毛玻璃效果。需要什么控件自行添加到toolbar上就OK。
初始化UIToolbar,设置toolbar样式为UIBarStyleBlackTranslucent或者UIBarStyleBlackOpaque 即可。修改bartintcolor的RGB值 可修改毛玻璃色调效果。
通过本人亲身尝试,其实UIToolBar,UINavigationBar,UITabbar在IOS7上都会有高斯效果,当然,有些机型不支持(后面会总结),然后他们的表现都是一模一样的,细微的差别就是各个控件上的边框多了一些圆角,横线,但是实现高斯效果的类都是用同一个。具体是什么类,可以去研究一下,这里不深入介绍那个类,只讲怎么使用
高斯效果有系统提供的有两种效果,白色底和黑色底。具体通过设置UIBarStyle属性去设置,有UIBarStyleDefault和UIBarStyleBlack,这两种效果对比起来,Black的效果最佳,所以现在在系统本身,都是用Black样式。
但是有人想,如果只有这两种样式,能不能通过修改一些属性去改变样式呢。下面尝试了几种方法
1.alpha值
通过修改alpha值,发现,如果alpha值不为1,那么就没有高斯效果,假如你对UIToolbar进行alpha值渐变,你会发现只有等到为1的时候才会有效果,所以alpha值不能修改,会导致高斯模糊失效
2.mask
由于UIToolbar只有是矩形的样式,我们可以通过mask属性对图像进行处理,通过根据我们自定的图形,mask对应的图形,但是,如果你使用了mask,那么很不好意思,高斯模糊没有了。
3.tintColor
设置了没效果
4.barTintColor
这个是设置bar 背景颜色,设置之后,发现有效果,但是效果不明显,有兴趣可以设置一下
至于其他属性,有兴趣可以去设置一下,我是没找到其他属性了
根据好几天的接触,发现了IOS7的高斯模糊的一个特点,由于系统是支持实时更新,这部分运算明显是有效率问题的,但是我们发现,系统的好像感觉不到效率问题。通过观察,发现,如果背景图片颜色比较单一,简单,高斯模糊效果很一般,有时候就只是简单的alpha透明过去,如果背景颜色块比较明显,那么高斯效果就很清晰,可见苹果对这个的处理还是做了优化,而不是每时每刻都在刷新界面,不然效率肯定提不上来。
机型限制,目前只支持IOS7系统,4s和以上的机型,touch5,ipad上屏幕较大,支持ipad4以上
示例代码:
@property (weak, nonatomic) IBOutlet UIToolbar *bottomTabsBarBlurBgView;
@property (weak, nonatomic) IBOutlet SingleSelectTabsView *bottomTabsBar;
- (void)awakeFromNib
{
[super awakeFromNib];
self.bottomTabsBarBlurBgView.barStyle = UIBarStyleBlack;
self.bottomTabsBarBlurBgView.hidden = IS_AT_LEAST_IOS7 ? NO : YES;
self.bottomTabsBar.alpha = IS_AT_LEAST_IOS7 ? 1 : 0.95;
self.bottomTabsBar.backgroundColor = IS_AT_LEAST_IOS7 ? UIColorFromRGB(255, 255, 255, 0) : UIColorFromRGB(25, 25, 25, 1);
}
方法二.通过图片处理+实时刷新的方法实现(但是有性能问题)
(1).工程中添加Accelerate.framework。
(2).添加Category文件UIImage+ImageEffects.h/UIImage+ImageEffects.m.
#import <UIKit/UIKit.h> @interface UIImage (ImageEffects) - (UIImage *)applyLightEffect; - (UIImage *)applyExtraLightEffect; - (UIImage *)applyDarkEffect; - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage; @end
#import "UIImage+ImageEffects.h" #import <Accelerate/Accelerate.h> #import <float.h> @implementation UIImage (ImageEffects) - (UIImage *)applyLightEffect { UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3]; return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; } - (UIImage *)applyExtraLightEffect { UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82]; return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; } - (UIImage *)applyDarkEffect { UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73]; return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; } - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor { const CGFloat EffectColorAlpha = 0.6; UIColor *effectColor = tintColor; int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor); if (componentCount == 2) { CGFloat b; if ([tintColor getWhite:&b alpha:NULL]) { effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha]; } } else { CGFloat r, g, b; if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) { effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha]; } } return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil]; } - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage { // Check pre-conditions. if (self.size.width < 1 || self.size.height < 1) { NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self); return nil; } if (!self.CGImage) { NSLog (@"*** error: image must be backed by a CGImage: %@", self); return nil; } if (maskImage && !maskImage.CGImage) { NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage); return nil; } CGRect imageRect = { CGPointZero, self.size }; UIImage *effectImage = self; BOOL hasBlur = blurRadius > __FLT_EPSILON__; BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; if (hasBlur || hasSaturationChange) { UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); CGContextRef effectInContext = UIGraphicsGetCurrentContext(); CGContextScaleCTM(effectInContext, 1.0, -1.0); CGContextTranslateCTM(effectInContext, 0, -self.size.height); CGContextDrawImage(effectInContext, imageRect, self.CGImage); vImage_Buffer effectInBuffer; effectInBuffer.data = CGBitmapContextGetData(effectInContext); effectInBuffer.width = CGBitmapContextGetWidth(effectInContext); effectInBuffer.height = CGBitmapContextGetHeight(effectInContext); effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext); UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); CGContextRef effectOutContext = UIGraphicsGetCurrentContext(); vImage_Buffer effectOutBuffer; effectOutBuffer.data = CGBitmapContextGetData(effectOutContext); effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext); effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext); effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext); if (hasBlur) { // A description of how to compute the box kernel width from the Gaussian // radius (aka standard deviation) appears in the SVG spec: // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement // // For larger values of 's' (s >= 2.0), an approximation can be used: Three // successive box-blurs build a piece-wise quadratic convolution kernel, which // approximates the Gaussian kernel to within roughly 3%. // // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) // // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel. // CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale]; NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5); if (radius % 2 != 1) { radius += 1; // force radius to be odd so that the three box-blur methodology works. } vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); } BOOL effectImageBuffersAreSwapped = NO; if (hasSaturationChange) { CGFloat s = saturationDeltaFactor; CGFloat floatingPointSaturationMatrix[] = { 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 0, 0, 0, 1, }; const int32_t divisor = 256; NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]); int16_t saturationMatrix[matrixSize]; for (NSUInteger i = 0; i < matrixSize; ++i) { saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor); } if (hasBlur) { vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); effectImageBuffersAreSwapped = YES; } else { vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); } } if (!effectImageBuffersAreSwapped) effectImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); if (effectImageBuffersAreSwapped) effectImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } // Set up output context. UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); CGContextRef outputContext = UIGraphicsGetCurrentContext(); CGContextScaleCTM(outputContext, 1.0, -1.0); CGContextTranslateCTM(outputContext, 0, -self.size.height); // Draw base image. CGContextDrawImage(outputContext, imageRect, self.CGImage); // Draw effect image. if (hasBlur) { CGContextSaveGState(outputContext); if (maskImage) { CGContextClipToMask(outputContext, imageRect, maskImage.CGImage); } CGContextDrawImage(outputContext, imageRect, effectImage.CGImage); CGContextRestoreGState(outputContext); } // Add in color tint. if (tintColor) { CGContextSaveGState(outputContext); CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); CGContextFillRect(outputContext, imageRect); CGContextRestoreGState(outputContext); } // Output image is ready. UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return outputImage; } @end
(3).使用Sample代码(图片可以通过截屏背景得到,从而有磨砂透明的盖层效果)。————>苹果官方Demo<————
- (void)viewDidLoad { [super viewDidLoad]; const CGFloat fontSize = 25.f; const NSString *text = @"Over layer string."; CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Avenir Next" size:fontSize]}]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 200, size.width, size.height)]; label.font = [UIFont fontWithName:@"Avenir Next" size:fontSize]; label.textAlignment = NSTextAlignmentNatural; label.backgroundColor = [UIColor clearColor]; label.text = (NSString *)text; UIImage *image = [UIImage imageNamed:@"wat.png"]; UIImage *blurredImage = [image applyBlurWithRadius:10 tintColor:[UIColor colorWithWhite:0 alpha:0.25] saturationDeltaFactor:1.f maskImage:nil]; UIImageView *imageView = [[UIImageView alloc] initWithImage:blurredImage]; imageView.frame = CGRectMake(0, 0, 500, 375); CGFloat imgScale = image.scale; CGRect labelFrame = label.frame; CGRect realRect = CGRectMake(labelFrame.origin.x * imgScale, labelFrame.origin.y * imgScale, labelFrame.size.width * imgScale, labelFrame.size.height * imgScale); CGImageRef labelPatternImage = CGImageCreateWithImageInRect(image.CGImage, realRect); label.textColor = [UIColor colorWithPatternImage:[UIImage imageWithCGImage:labelPatternImage scale:image.scale orientation:UIImageOrientationUp]]; CGImageRelease(labelPatternImage); [self.view addSubview:imageView]; [self.view addSubview:label]; }
相关文章推荐
- ios开发者必知的75个工具
- iOS开发之CGPoint、CGSize、CGRect、CGRectMake、window(窗口)、视图(view)
- IOS 协议与代理 的小注
- iOS5兼容 framework Optional
- ios 向工程里添加Fonts
- IOS---NSThread同步处理
- iOS 向模拟器里添加照片
- ios多线程-GCD
- ios多线程的对比
- IOS---线程
- CATransition的动画效果类型及实现方法
- iOS图片拉伸技巧
- [iOS]单例
- [iOS]获得当前时间(NSDate )
- 分析理解iOS生命周期
- HDOJ1017 A Mathematical Curiosity
- HDOJ1017 A Mathematical Curiosity
- ArcGIS Runtime SDK for iOS开发系列教程(7)——GeometryService与GeometryEngine使用
- ArcGIS Runtime SDK for iOS开发系列教程(6)——Tasks使用的一般流程
- UVA 11111 - Generalized Matrioshkas