iOS毛玻璃效果的实现及图片模糊效果的三种方法

iOS毛玻璃效果的实现及图片模糊效果的三种方法

2023年7月14日发(作者:)

iOS⽑玻璃效果的实现及图⽚模糊效果的三种⽅法App设计时往往会⽤到⼀些模糊效果或者⽑玻璃效果,iOS⽬前已提供⼀些模糊API可以让我们⽅便是使⽤。话说苹果在iOS7.0之后,很多系统界⾯都使⽤了⽑玻璃效果,增加了界⾯的美观性,⽐如下图的通知中⼼界⾯;但是其iOS7.0的SDK并没有提供给开发者实现⽑玻璃效果的API,所以很多⼈都是通过⼀些别⼈封装的框架来实现,后⾯我也会讲到⼀个;其实在iOS7.0(包括)之前还是有系统的类可以实现⽑玻璃效果的, 就是 UIToolbar这个类,并且使⽤相当简单,⼏⾏代码就可以搞定.下⾯是代码实现:创建⼀个UIToolbar实例,设置它的frame或者也可以通过添加约束然后UIToolbar有⼀个属性:barStyle,设置对应的枚举值来呈现⽑玻璃的样式,最后再添加到需要进⾏⽑玻璃效果的view上即可./*⽑玻璃的样式(枚举)UIBarStyleDefault = ,UIBarStyleBlack = ,UIBarStyleBlackOpaque = , // Deprecated. Use UIBarStyleBlackUIBarStyleBlackTranslucent = , // Deprecated. Use UIBarStyleBlack and set the translucent property to YES*/UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:]; = [UIImage imageNamed:@""];[ addSubview:bgImgView];UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(, , *., )];le = UIBarStyleBlackTranslucent;[bgImgView addSubview:toolbar];

效果图:我们再来看看视图结构:通过视图结构可以看到UIToolbar包含了三个⼦视图⼀个背景图⽚和1个背景view,还有1个背景特效view,正是这⼏个视图结合在⼀起实现了⽑玻璃的效果在iOS8.0之后,苹果新增了⼀个类UIVisualEffectView,通过这个类来实现⽑玻璃效果与上⾯的UIToolbar⼀样,⽽且效率也⾮常之⾼,使⽤也是⾮常简单,⼏⾏代码搞定. UIVisualEffectView是⼀个抽象类,不能直接使⽤,需通过它下⾯的三个⼦类来实现(UIBlurEffect, UIVisualEffevt, UIVisualEffectView);⼦类UIBlurEffect只有⼀个类⽅法,⽤来快速创建⼀个⽑玻璃效果,参数是⼀个枚举,⽤来设置⽑玻璃的样式,⽽UIVisualEffectView则多了两个属性和两个构造⽅法,⽤来快速将创建的⽑玻璃添加到这个UIVisualEffectView上.特别注意: 这个类是iOS8.0之后才适⽤, 所以如果项⽬要兼容iOS7.0的话, 还是要考虑其它的两种⽅法了.下⾯来看看实现代码:同样是先快速的实例化UIBlurEffect并设置⽑玻璃的样式,然后再通过UIVisualEffectView的构造⽅法将UIBlurEffect的实例添加上去最后设置frame或者是通过添加约束, 将effectView添加到要实现了⽑玻璃的效果的view控件上,效果图和上⾯的⼀样.UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:]; = [UIImage imageNamed:@""];tMode = UIViewContentModeScaleAspectFill;//[bgImgView setImageToBlur: [UIImage imageNamed:@""] blurRadius: completionBlock:nil];teractionEnabled = YES;[ addSubview:bgImgView];/*⽑玻璃的样式(枚举)UIBlurEffectStyleExtraLight,UIBlurEffectStyleLight,UIBlurEffectStyleDark*/UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect]; = CGRectMake(, , *., );[bgImgView addSubview:effectView];

但是我们来看看视图结构,⼤家会发现和Toolbar不⼀样哦!其实是因为UIVisualEffectView这个类,构造⽅法帮我们创建了⼀个view,⽽这个view我们给它做了⽑玻璃处理,再将其覆盖到了背景图之上嗯! 最后再来给⼤家介绍⼀个国外⼤神封装的UIImageView的分类,⾥⾯不管是怎么实现的,反正使⽤⾮常简单,只要⼀句代码就搞定.下⾯先看代码:UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:];// = [UIImage imageNamed:@""];tMode = UIViewContentModeScaleAspectFill;// 对背景图⽚进⾏⽑玻璃效果处理 参数blurRadius默认是,可指定,最后⼀个参数block回调可以为nil[bgImgView setImageToBlur: [UIImage imageNamed:@""] blurRadius: completionBlock:nil];teractionEnabled = YES;[ addSubview:bgImgView];

效果图:再来看看添加⽑玻璃效果后的视图结构:哈哈哈, ⼤家应该看懂了, 这是直接对背景图⽚进⾏了⾼斯模糊处理了,其它就不解释了.好啦, 反正iOS中要进⾏⽑玻璃效果处理就这⼏种⽅式,看⼤家的需求,喜欢⽤哪种就⽤哪种吧.上⾯的demo,包括⼤神封装的分类,如果需要详细的源代码的话,可以到我的gitHub上Clone啦!有问题欢迎留⾔⼀起探讨学习.下⾯给⼤家介绍图⽚模糊效果的三种⽅法第⼀种使⽤Core Image进⾏模糊- (UIImage *)blurryImage:(UIImage *)image

withBlurLevel:(CGFloat)blur {

CIImage *inputImage = [CIImage imageWithCGImage:e];

CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"

keysAndValues:kCIInputImageKey, inputImage,

@"inputRadius", @(blur),

]; CIImage *outputImage = Image;

CGImageRef outImage = [t createCGImage:outputImage

fromRect:[outputImage extent]];

return [UIImage imageWithCGImage:outImage]; }第⼆种使⽤vImage API进⾏模糊- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {

if (blur < 0.f || blur > 1.f) {

blur = 0.5f;

}

int boxSize = (int)(blur * 100);

boxSize = boxSize - (boxSize % 2) + 1;

CGImageRef img = e;

vImage_Buffer inBuffer, outBuffer;

vImage_Error error;

void *pixelBuffer;

CGDataProviderRef inProvider = CGImageGetDataProvider(img);

CFDataRef inBitmapData = /code/view/CGDataProviderCopyData(inProvider);

= CGImageGetWidth(img);

= CGImageGetHeight(img);

es = CGImageGetBytesPerRow(img);

= (void*)CFDataGetBytePtr(inBitmapData);

pixelBuffer = malloc(CGImageGetBytesPerRow(img) *

CGImageGetHeight(img));

if(pixelBuffer == NULL)

NSLog(@"No pixelbuffer");

= pixelBuffer;

= CGImageGetWidth(img);

= CGImageGetHeight(img);

es = CGImageGetBytesPerRow(img); error = vImageBoxConvolve_ARGB8888(&inBuffer,

&outBuffer,

NULL,

0,

0,

boxSize,

boxSize,

NULL,

kvImageEdgeExtend);

if (error) {

NSLog(@"error from convolution %ld", error);

}

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef ctx = CGBitmapContextCreate(

,

,

,

8,

es,

colorSpace,

kCGImageAlphaNoneSkipLast);

CGImageRef imageRef = CGBitmapContextCreateImage (ctx);

UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

//clean up

CGContextRelease(ctx);

CGColorSpaceRelease(colorSpace);

free(pixelBuffer);

CFRelease(inBitmapData);

CGColorSpaceRelease(colorSpace);

CGImageRelease(imageRef);

return returnImage; }

第三种⽅法是⽹上找到的(⽑玻璃效果)// 内部⽅法,核⼼代码,封装了⽑玻璃效果 参数:半径,颜⾊,⾊彩饱和度- (UIImage *)imageBluredWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage {

CGRect imageRect = { CGPointZero, };

UIImage *effectImage = self; BOOL hasBlur = blurRadius > __FLT_EPSILON__;

BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; if (hasBlur || hasSaturationChange) { UIGraphicsBeginImageContextWithOptions(, NO, [[UIScreen mainScreen] scale]);

CGContextRef effectInContext = UIGraphicsGetCurrentContext();

CGContextScaleCTM(effectInContext, 1.0, -1.0);

CGContextTranslateCTM(effectInContext, 0, -);

CGContextDrawImage(effectInContext, imageRect, e);

vImage_Buffer effectInBuffer; = /code/view/CGBitmapContextGetData(effectInContext);

= CGBitmapContextGetWidth(effectInContext);

= CGBitmapContextGetHeight(effectInContext);

es = CGBitmapContextGetBytesPerRow(effectInContext);

UIGraphicsBeginImageContextWithOptions(, NO, [[UIScreen mainScreen] scale]);

CGContextRef effectOutContext = UIGraphicsGetCurrentContext();

vImage_Buffer effectOutBuffer;

= CGBitmapContextGetData(effectOutContext);

= CGBitmapContextGetWidth(effectOutContext);

= CGBitmapContextGetHeight(effectOutContext);

es = 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, (short)radius, (short)radius, 0, kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, (short)radius, (short)radius, 0, kvImageEdgeE}

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(, NO, [[UIScreen mainScreen] scale]);

CGContextRef outputContext = UIGraphicsGetCurrentContext();

CGContextScaleCTM(outputContext, 1.0, -1.0);

CGContextTranslateCTM(outputContext, 0, -);

// 开始画底图 CGContextDrawImage(outputContext, imageRect, e);

// 开始画模糊效果

if (hasBlur){

CGContextSaveGState(outputContext);

if (maskImage)

{

CGContextClipToMask(outputContext, imageRect, e);

} CGContextDrawImage(outputContext, imageRect, e);

CGContextRestoreGState(outputContext);

}

// 添加颜⾊渲染

if (tintColor){

CGContextSaveGState(outputContext);

CGContextSetFillColorWithColor(outputContext, r);

CGContextFillRect(outputContext, imageRect);

CGContextRestoreGState(outputContext);

}

// 输出成品,并关闭上下⽂

UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return outputImage;}

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689265290a226460.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信