下面给大家介绍图片模糊效果的三种方法

第一种使用Core Image进行模糊

- (UIImage *)blurryImage:(UIImage *)image 

withBlurLevel:(CGFloat)blur { 

CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage]; 

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

keysAndValues:kCIInputImageKey, inputImage, 

@"inputRadius", @(blur), 

]; CIImage *outputImage = filter.outputImage; 

CGImageRef outImage = [self.context createCGImage:outputImage 

fromRect:[outputImage extent]]; 

return [UIImage imageWithCGImage:outImage]; }

第二种使用vImage API进行模糊

- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur { 

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

blur = 0.5f; 

} 

int boxSize = (int)(blur * ); 

boxSize = boxSize - (boxSize % ) + ; 

CGImageRef img = image.CGImage; 

vImage_Buffer inBuffer, outBuffer; 

vImage_Error error; 

void *pixelBuffer; 

CGDataProviderRef inProvider = CGImageGetDataProvider(img); 

CFDataRef inBitmapData = http://www.open-open.com/code/view/CGDataProviderCopyData(inProvider); 

inBuffer.width = CGImageGetWidth(img); 

inBuffer.height = CGImageGetHeight(img); 

inBuffer.rowBytes = CGImageGetBytesPerRow(img); 

inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData); 

pixelBuffer = malloc(CGImageGetBytesPerRow(img) * 

CGImageGetHeight(img)); 

if(pixelBuffer == NULL) 

NSLog(@"No pixelbuffer"); 

outBuffer.data = pixelBuffer; 

outBuffer.width = CGImageGetWidth(img); 

outBuffer.height = CGImageGetHeight(img); 

outBuffer.rowBytes = CGImageGetBytesPerRow(img); 

error = vImageBoxConvolve_ARGB8888(&inBuffer, 

&outBuffer, 

NULL, 

, 

, 

boxSize, 

boxSize, 

NULL, 

kvImageEdgeExtend); 

if (error) { 

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

} 

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

CGContextRef ctx = CGBitmapContextCreate( 

outBuffer.data, 

outBuffer.width, 

outBuffer.height, 

, 

outBuffer.rowBytes, 

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, self.size }; 

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

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

CGContextRef effectInContext = UIGraphicsGetCurrentContext(); 

CGContextScaleCTM(effectInContext, 1.0, -1.0); 

CGContextTranslateCTM(effectInContext, , -self.size.height); 

CGContextDrawImage(effectInContext, imageRect, self.CGImage); 

vImage_Buffer effectInBuffer; effectInBuffer.data = http://www.open-open.com/code/view/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 * . * sqrt( * M_PI) /  + 0.5); 

if (radius %  != ) { 

radius += ; // force radius to be odd so that the three box-blur methodology works. 

} 

vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, , , (short)radius, (short)radius, , kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, , , (short)radius, (short)radius, , kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, , , (short)radius, (short)radius, , 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.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 

, 

0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 

, 

, 

, 

, 

, 

}; 

const int32_t divisor = ; 

NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[]); int16_t saturationMatrix[matrixSize]; for (NSUInteger i = ; 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, , -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;}

iOS - 图片模糊效果实现的更多相关文章

  1. iOS图片模糊效果与阴影效果

    /** 添加图片模糊效果 @parms  要添加模糊效果的view @return */ + (UIVisualEffectView *)addVisualEffectViewWithView:(UI ...

  2. iOS图片模糊效果

    增加  CoreImage.framework  CoreGraphic.framework 等库 在使用时引入:#import <Accelerate/Accelerate.h> ,支持 ...

  3. iOS 图片背景模糊效果

    iOS 图片背景模糊效果 1.使用CoreImage中的模糊滤镜 原始效果图如下: CoreImage的实现: - (void)viewDidLoad { [super viewDidLoad]; / ...

  4. 实现iOS图片等资源文件的热更新化(三):动态的资源文件夹

    简介 此文,将尝试动态从某个不确定的文件夹中加载资源文件.文章,会继续完善自定义的 imageNamed 函数,并为下一篇文章铺垫. 这么做的意义 正如我们经常所说的那样,大多数情景知道做事的意义往往 ...

  5. iOS 图片轮播图(自动滚动)

    iOS 图片轮播图(自动滚动) #import "DDViewController.h" #define DDImageCount 5 @interface DDViewContr ...

  6. jquery mobile上传图片完整例子(包含ios图片横向问题处理和C#后台图片压缩)

    上传图片本身是个基本的小功能,但是到了移动端就不那么简单了,相信找到这篇文章的你一定有深深的同感. 本文实例是:在(移动端)页面中点击图片,然后选择文件,然后保存.使用Asp.net 难点一:后台获取 ...

  7. iOS图片加载到内存中占用内存情况

    我的测试结果: 图片占用内存   图片尺寸           .png文件大小 1MB              512*512          316KB 4MB              10 ...

  8. 实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面

    简介 一个简单的关于页面,有一个图片,版本号,App名称等,着重演示各个系列的文章完整集成示例. 动机与意义 这是系列文章的最后一篇.今天抽空写下,收下尾.文章本身会在第四篇的基础上,简单扩充下代码, ...

  9. 实现iOS图片等资源文件的热更新化(零): 序

    必要的序 以后在写系列文章,准备把基本的规划和动机等,单独作为一个小的序言部分给独立出来.序言部分,可以较为完整地交待系列文章的写作动机,所展示的编码技术可能的应用场景等.个人,我还是比较看重文章或者 ...

随机推荐

  1. PHP curl put方式上传文件

    发送端: <?php function curlPut($destUrl, $sourceFileDir, $headerArr = array(), $timeout = ) { $ch = ...

  2. ubuntu上的 /dev/loop0 到 /dev/loop18占到100%的处理

    date : 2019-08-13  09:39:09 author: headsen  chen 处理方法:apt autoremove --purge snapd 再次检测:

  3. SpringBoot启动嵌入式tomcat源码解读

    一.SpringBoot自动拉起Tomcat SpringBoot框架是当前比较流行的java后端开发框架,与maven结合大大简化了开发人员项目搭建的步骤,我们知道SpringBoot的启动类启动后 ...

  4. RabbitMQ 清除全部队列及消息

    前言 安装RabbitMQ后可访问:http://{rabbitmq安装IP}:15672使用(默认的是帐号guest,密码guest.此账号只能在安装RabbitMQ的机器上登录,无法远程访问登录. ...

  5. 解决软件卸载时Abstract: "Invalid serial number" xe4

    In RAD Studio, Delphi, C++Builder, XE4 there can become a scenario if you try to modify, repair, upg ...

  6. 【大产品思路】Amazon

    http://www.woshipm.com/it/2844056.html 强烈赞同,对复杂业务,分布团队和开发可以借鉴. “ 这种公司级“微服务(Microservice)”架构的好处在于,每个团 ...

  7. 【转】do...while(0)的妙用

    前言 今天无意中看到这个标题,因为好奇就点进去了,不错,又学习啦... 具体内容: 1. do...while(0)消除goto语句: 2 宏定义中的do...while(0): 参考 1. 原链接_ ...

  8. 前端研究CSS之内联元素块级化/区域大小/文字和图标的位置

    做了一天的小按钮基本都是文字+小图标的组合,问题挺多处理的不好,现在总结一下做个了断. //页面结构 <span class="b"> <a href=" ...

  9. vue 跨域简记

    0.服务端设置 app.use(function(req, res, next){ //设置跨域访问 res.header('Access-Control-Allow-Origin', '*'); r ...

  10. SQLServer分页查询方法整理以及批量插入操作SqlBulkCopy

    分页查询 通用方法:sqlserver 2005 + ROW_NUMBER() OVER()方式: ; TOP NOT IN方式 : ID FROM TripDetail ORDER BY ID) O ...