关闭

iOS图片模糊效果

146人阅读 评论(0) 收藏 举报

在开发中,有时候我们可能会做一些图片模糊的效果,来给APP添加色彩。自己看到一个APP的模糊效果,感觉很不错,所以就学了下如何来实现这样一个模糊效果,写下来方便自己回顾,有需要的童鞋也可以get下,还包含一个截屏功能哦~

先看效果图:

                   

                                       模糊前                                                                                                    模糊后

因为只是显示一个小功能,所以我都写在了ViewController文件里,要开发具备这个效果的App的童鞋最好单独抽出一个类来实现这个功能。

来看看代码,解释都写在注释里了。

#import "ViewController.h"
#import <Accelerate/Accelerate.h>

@interface ViewController ()
@property(nonatomic,strong)UIImageView *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIImageView *imageView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1"]];
    imageView.frame=self.view.bounds;
    self.imageView=imageView;
    [self.view addSubview:imageView];
    
    UIButton *blurBtn=[[UIButton alloc]init];
    blurBtn.frame=CGRectMake(10, 64, 100, 30);
    [blurBtn setTitle:@"按下变模糊" forState:UIControlStateNormal];
    blurBtn.backgroundColor=[UIColor blackColor];
    [blurBtn addTarget:self action:@selector(setBlurImageClick) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:blurBtn];
    
}
-(void)setBlurImageClick
{
    UIImage *image=[self screenShot:self.view];
    UIImage *imageBlur=[self blurryImage:image withBlurLevel:0.3f];
    
    [self.imageView setImage:imageBlur];
}
/**
 截图,返回一张截取的图片
 这里的view为window窗口
 */
- (UIImage *) screenShot:(UIView *)window
{
    CGSize size=window.bounds.size;
    
    UIGraphicsBeginImageContextWithOptions(size, NO, 2.0);
    [window.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    NSData *imageData=UIImageJPEGRepresentation(image, 0.75);
    image=[UIImage imageWithData:imageData];
    
    return image;
}

/**
 返回一张模糊图片
 使用vImage API进行模糊
 需要导入头文件#import <Accelerate/Accelerate.h>
 */
- (UIImage *) blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur
{
    if ((blur < 0.1f) || (blur > 2.0f)) {
        blur=0.5f;
    }
    int boxSize=(int)(blur * 40);
    boxSize=boxSize-(boxSize % 2)+1;
    
    CGImageRef img=image.CGImage;
    
    vImage_Buffer inBuffer,outBuffer;
    vImage_Error error;
    void *pixelBuffer;
    
    CGDataProviderRef inProvider=CGImageGetDataProvider(img);
    CFDataRef inBitmapData=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);
    
    void *pixelBuffer2=malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
    vImage_Buffer outBuffer2;
    outBuffer2.data=pixelBuffer2;
    outBuffer2.width=CGImageGetWidth(img);
    outBuffer2.height=CGImageGetHeight(img);
    outBuffer2.rowBytes=CGImageGetBytesPerRow(img);
    
    //vImageBoxConvolve_ARGB8888模糊算法函数
    error=vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    error=vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    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(outBuffer.data, outBuffer.width, outBuffer.height, 8, outBuffer.rowBytes, colorSpace, CGImageGetBitmapInfo(image.CGImage));
    
    CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
    
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    
    free(pixelBuffer);
    free(pixelBuffer2);
    CFRelease(inBitmapData);
    
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageRef);
    
    return returnImage;
}

/**
 返回模糊图片
 使用Core Image进行模糊
 */
//- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur
//{
//    CIContext *context=[CIContext contextWithOptions:nil];
//    CIImage *inputImage=[CIImage imageWithCGImage:image.CGImage];
//    CIFilter *filter=[CIFilter filterWithName:@"CIGaussianBlur" keysAndValues:kCIInputImageKey,inputImage,@"inputRadius", @(blur),nil];
//
//    CIImage *outputImage=filter.outputImage;
//
//    CGImageRef outImage=[context createCGImage:outputImage fromRect:[outputImage extent]];
//    return [UIImage imageWithCGImage:outImage];
//}

@end

点击按钮,屏幕就会变模糊。

查资料时看到也可以使用Core Image来进行图片模糊,但是我试了下,感觉效果不是很好,可能是因为现在对Core Image还不熟,所以不太理解它的使用,等我进一步对它学习吧,知道的大神也可以指教下。注释掉的部分就是用Core Image来实现的,高斯模糊,有兴趣的童鞋可以试试看,我这里运行的效果感觉不是模糊效果。

本例中用的是vImage API进行模糊,注意不要忘记导入#import<Accelerate/Accelerate.h>头文件。


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14639次
    • 积分:332
    • 等级:
    • 排名:千里之外
    • 原创:14篇
    • 转载:10篇
    • 译文:0篇
    • 评论:6条