多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > iOS_自定義毛玻璃效果

iOS_自定義毛玻璃效果

來源:程序員人生   發布時間:2014-09-24 20:11:27 閱讀次數:3031次

最終效果圖:








關鍵代碼:




UIImage分類代碼

// // UIImage+BlurGlass.h // 帥哥_團購 // // Created by beyond on 14-8-30. // Copyright (c) 2014年 com.beyond. All rights reserved. // 毛玻璃效果 UIImage分類 #import <UIKit/UIKit.h> @interface UIImage (BlurGlass) /* 1.白色,參數: 透明度 0~1, 0為白, 1為深灰色 半徑:默認30,推薦值 3 半徑值越大越模糊 ,值越小越清楚 色彩飽和度(濃度)因子: 0是黑白灰, 9是濃彩色, 1是原色 默認1.8 “彩度”,英文是稱Saturation,即飽和度。將無彩色的黑白灰定為0,最鮮艷定為9s,這樣大致分成十階段,讓數值和人的感官直覺一致。 */ - (UIImage *)imgWithLightAlpha:(CGFloat)alpha radius:(CGFloat)radius colorSaturationFactor:(CGFloat)colorSaturationFactor; // 2.封裝好,供外界調用的 - (UIImage *)imgWithBlur; @end


// // UIImage+BlurGlass.m // 帥哥_團購 // // Created by beyond on 14-8-30. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "UIImage+BlurGlass.h" #import <Accelerate/Accelerate.h> @implementation UIImage (BlurGlass) /* 1.白色,參數: 透明度 0~1, 0為白, 1為深灰色 半徑:默認30,推薦值 3 半徑值越大越模糊 ,值越小越清楚 色彩飽和度(濃度)因子: 0是黑白灰, 9是濃彩色, 1是原色 默認1.8 “彩度”,英文是稱Saturation,即飽和度。將無彩色的黑白灰定為0,最鮮艷定為9s,這樣大致分成十階段,讓數值和人的感官直覺一致。 */ - (UIImage *)imgWithLightAlpha:(CGFloat)alpha radius:(CGFloat)radius colorSaturationFactor:(CGFloat)colorSaturationFactor { UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:alpha]; return [self imgBluredWithRadius:radius tintColor:tintColor saturationDeltaFactor:colorSaturationFactor maskImage:nil]; } // 2.封裝好,供外界調用的 - (UIImage *)imgWithBlur { // 調用方法1 return [self imgWithLightAlpha:0.1 radius:3 colorSaturationFactor:1]; } // 內部方法,核心代碼,封裝了毛玻璃效果 參數:半徑,顏色,色彩飽和度 - (UIImage *)imgBluredWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage { 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) { 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(); } // 開啟上下文 用于輸出圖像 UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); CGContextRef outputContext = UIGraphicsGetCurrentContext(); CGContextScaleCTM(outputContext, 1.0, -1.0); CGContextTranslateCTM(outputContext, 0, -self.size.height); // 開始畫底圖 CGContextDrawImage(outputContext, imageRect, self.CGImage); // 開始畫模糊效果 if (hasBlur) { CGContextSaveGState(outputContext); if (maskImage) { CGContextClipToMask(outputContext, imageRect, maskImage.CGImage); } CGContextDrawImage(outputContext, imageRect, effectImage.CGImage); CGContextRestoreGState(outputContext); } // 添加顏色渲染 if (tintColor) { CGContextSaveGState(outputContext); CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); CGContextFillRect(outputContext, imageRect); CGContextRestoreGState(outputContext); } // 輸出成品,并關閉上下文 UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return outputImage; } @end

控制器代碼

// // MineController.m // 帥哥_團購 // // Created by beyond on 14-8-14. // Copyright (c) 2014年 com.beyond. All rights reserved. // dock上面的【我的】按鈕對應的控制器 #import "MineController.h" #import "ImgDownloadTool.h" #import <Accelerate/Accelerate.h> #import "UIImage+BoxBlur.h" #import "GirlCell.h" // 每一個格子的寬和高 #define kItemW 240 #define kItemH 320 @interface MineController ()<UICollectionViewDataSource,UICollectionViewDelegate> { NSMutableArray *_imgArr; UIWebView *_webView; // 添加一個coverImgView,用于點擊了cell時,進行屏幕截圖并加上毛玻璃效果,置于最上方作為蒙板 UIImageView *_coverBlurImgView; // 點擊cell,彈出一個大圖(必須在控制器顯示之前 再確定frame,真實的frame) UIImageView *_showingImgView; } @end @implementation MineController #pragma mark - 生命周期方法 - (void)viewDidLoad { [super viewDidLoad]; self.title = @"我的青春誰做主"; // 0.加載plist文件保存的url數組 // sg_bundle模板代碼,1,獲得.app主要的包;2,返回主要的包中某個文件的fullPath全路徑 NSBundle *mainBundle = [NSBundle mainBundle]; NSString *fullPath = [mainBundle pathForResource:@"sinaImgArr.plist" ofType:nil]; _imgArr = [NSArray arrayWithContentsOfFile:fullPath]; // 1.創建自己的collectionView [self addCollectionView]; // 2.注冊cell格子要用到的xib文件 [self.collectionView registerNib:[UINib nibWithNibName:@"GirlCell" bundle:nil] forCellWithReuseIdentifier:@"GirlCell"]; // 3.設置collectionView永遠支持垂直滾動,為下拉刷新準備(彈簧) self.collectionView.alwaysBounceVertical = YES; // 4.設置collectionView的背景色 self.collectionView.backgroundColor = kGlobalBg; // 5.添加一個coverImgView,用于點擊了cell時,進行屏幕截圖并加上毛玻璃效果,置于最上方作為蒙板 _coverBlurImgView = [[UIImageView alloc]init]; [self.view addSubview:_coverBlurImgView]; // 6.點擊cell,彈出一個大圖(必須在控制器顯示之前 再確定frame,真實的frame) _showingImgView = [[UIImageView alloc]init]; _showingImgView.backgroundColor = [UIColor clearColor]; [self.view addSubview:_showingImgView]; _showingImgView.contentMode = UIViewContentModeScaleAspectFit; _showingImgView.userInteractionEnabled = YES; [_showingImgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showingImgTap)]]; } // 1.創建自己的collectionView - (void)addCollectionView { // 創建一個流布局,必須指定 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; // 設置流布局里面的每一個格子寬和高,即每一個網格的尺寸 layout.itemSize = CGSizeMake(kItemW, kItemH); // 每一行之間的間距 layout.minimumLineSpacing = 20; // 指定的流布局創建一個collectionView,并且用成員變量記住 self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; // 高度和寬度自動伸縮 self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; self.collectionView.delegate = self; self.collectionView.dataSource = self; [self.view addSubview:self.collectionView]; } #pragma mark 在viewWillAppear和viewDidAppear中可以取得view最準確的寬高(width和height) // 重要~~~因為在控制器創建時,寬默認是768,高默認是1024,不管橫豎屏 // 只有在viewWillAppear和viewDidAppear方法中,可以取得view最準確的(即實際的)寬和高(width和height) - (void)viewWillAppear:(BOOL)animated { // 默認計算layout [self didRotateFromInterfaceOrientation:0]; } #pragma mark - 父類方法 // 攔截,屏幕即將旋轉的時候調用(控制器監控屏幕旋轉) - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { //log(@"屏幕即將旋轉"); } #pragma mark 屏幕旋轉完畢的時候調用 // 攔截,屏幕旋轉完畢的時候調用 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { // 1.取出創建CollectionViewController時傳入的的UICollectionViewFlowLayout UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout; // 2.計算間距 CGFloat v = 0; CGFloat h = 0; CGFloat height = self.view.frame.size.height -44; CGFloat width = self.view.frame.size.width; if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation) ) { // 橫屏的間距 v = (height - 2 * kItemH) / 3; h = (width - 3 * kItemW) / 4; } else { // 豎屏的間距 v = (height - 3 * kItemH) / 4; h = (width - 2 * kItemW) / 3; } // 3.動畫調整格子之間的距離 [UIView animateWithDuration:4.0 animations:^{ // 上 左 下 右 四個方向的margin layout.sectionInset = UIEdgeInsetsMake(h, h, v, h); // 每一行之間的間距 layout.minimumLineSpacing = h; }]; // 4.旋轉完成之后,才可以得到真實的frame,暫時隱藏起來,當點擊cell的時侯才展示 -5 _coverBlurImgView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height); _coverBlurImgView.hidden = YES; _showingImgView.hidden = YES; CGRect temp = _showingImgView.frame; CGFloat x =self.view.frame.size.width * 0.5; CGFloat y =self.view.frame.size.height * 0.5; temp = CGRectMake(x,y, 0, 0); _showingImgView.frame = temp; } #pragma mark - collectionView代理方法 // 共有多少個Item(就是格子Cube),詢問子類 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return _imgArr.count; } #pragma mark 刷新數據的時候會調用(reloadData) #pragma mark 每當有一個cell重新進入屏幕視野范圍內就會調用 // 生成每一個獨一無二的格子,詢問子類 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"GirlCell"; GirlCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; cell.imgSrc = _imgArr[indexPath.row]; return cell; } // 點擊了一個格子時,1,截屏,2,動畫毛玻璃圖片,3,showing從小放到大 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { // 1,截屏 [self screenShot]; // 2,顯示 _coverBlurImgView.alpha = 1; _coverBlurImgView.hidden = NO; // 3.調用UIImage的分類方法,進行毛玻璃處理 _coverBlurImgView.image = [_coverBlurImgView.image imgWithBlur]; // 4.展示_showingImgView _showingImgView.hidden = NO; // 點擊cell,彈出一個大圖 CGRect temp = _showingImgView.frame; CGFloat x =self.view.frame.size.width * 0.5; CGFloat y =self.view.frame.size.height * 0.5; temp = CGRectMake(x,y, 0, 0); _showingImgView.frame = temp; _showingImgView.alpha = 0; [UIView animateWithDuration:0.5 animations:^{ [ImgDownloadTool imgDownloadWithUrl:_imgArr[indexPath.row] tmpImgName:kImgPlaceHolder imageView:_showingImgView]; _showingImgView.alpha = 1; _showingImgView.frame = self.view.bounds; }]; } // 使用上下文截圖,并使用指定的區域裁剪,模板代碼 - (void)screenShot { // 將要被截圖的view // 背景圖片 總的大小 CGSize size = self.view.frame.size; UIGraphicsBeginImageContext(size); // 開啟上下文,使用參數之后,截出來的是原圖(YES 0.0 質量高) UIGraphicsBeginImageContextWithOptions(size, YES, 0.0); // 裁剪的關鍵代碼,要裁剪的矩形范圍 CGRect rect = CGRectMake(0, 0, size.width, size.height ); //注:iOS7以后renderInContext:由drawViewHierarchyInRect:afterScreenUpdates:替代 [self.view drawViewHierarchyInRect:rect afterScreenUpdates:NO]; // 從上下文中,取出UIImage UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); // 添加截取好的圖片到圖片View里面 _coverBlurImgView.image = snapshot; // 千萬記得,結束上下文(移除棧頂上下文) UIGraphicsEndImageContext(); } // 正在顯示的大圖被點了 - (void)showingImgTap { [UIView animateWithDuration:0.5 animations:^{ CGRect temp = _showingImgView.frame; CGFloat x =self.view.frame.size.width * 0.5; CGFloat y =self.view.frame.size.height * 0.5; temp = CGRectMake(x,y, 0, 0); _showingImgView.frame = temp; _showingImgView.alpha = 0; } completion:^(BOOL finished) { // 隱藏起來 _showingImgView.hidden = YES; _coverBlurImgView.hidden = YES; }]; } #pragma mark - 生命周期方法 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end









生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 最近的中文字幕免费视频1 最近的中文字幕免费完整 最近的中文字幕视频大全高清 | 国产大片免费天天看 | 国产欧美日韩综合精品无毒 | 欧美a级在线 | japanhdⅹxxxhd日本| 亚洲国产综合视频 | 亚洲欧美视频一区二区三区 | 欧美亚洲国产精品久久第一页 | 中文字幕乱码在线观看 | 国产成人a一区二区 | 中文字幕免费在线观看 | 亚洲欧美视频一区二区三区 | 国产成人福利美女观看视频 | 久久久免费的精品 | free性欧美xxx | 久久 精品 一区二区 | 国产成人亚洲精品久久 | 男人和女人全黄一级毛片 | 国产91极品福利手机观看 | 国产大片免费观看中文字幕 | 日韩亚洲国产欧美精品 | 狠狠涩 | 多人做人爱视频在线观看 | 91porn国产在线观看 | 久久福利一区二区三区 | www亚洲成人 | 国产一区二区三区高清视频 | 亚洲 欧美 另类 综合 日韩 | h视频在线观看视频观看 | 亚洲依依成人精品 | 久久se精品一区二区国产 | 国产在线精品福利一区二区三区 | free×性欧美hd | 欧美亚洲国产日韩 | 亚洲精品美女久久久aaa | 国产成人久久综合漫画 | 黄色毛片播放 | 欧美两性人xxxx高清免费 | 五月天婷婷一区二区三区久久 | 国产视频久久久 | 日本三级成人午夜视频网 |