一种高斯模糊渐变动画的实现

关于高斯模糊的方式有很多种,但是如果需要模糊渐变,那么对这种高斯模糊算法的性能要求是比较高的,今天这里重点不讨论算法,只是提供一个动画实现的思路。动画效果如下:


高斯模糊渐变动画

高斯模糊

-(UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur
{
    if (blur < 0.f || blur > 1.f) {
      blur = 0.5f;
    }
   int boxSize = (int)(blur * 250);
    boxSize = boxSize - (boxSize % 2) + 1;
    CGImageRef img = image.CGImage;
    vImage_Buffer inBuffer, outBuffer;
    vImage_Error error;
    void *pixelBuffer;
    //从CGImage中获取数据
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
    //设置从CGImage获取对象的属性
    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, 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, 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;
}

高斯模糊渐变

自动渐变的过程需要加入一个定时器NSTimer,并且循环。每0.1秒循环一次,通过一个变量来计数,以改变blur值。当然,这里的参数根据需要来调整来满足不同的需求。

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(changeImageView1) userInfo:nil repeats:YES];

-(void)changeImageView1
{
    self.imageView1.image = [self boxblurImage:[UIImage imageNamed:@"login_bg_1"] withBlurNumber:self.count1/50.0];
    if (self.count1++ == 15) {
        [self.timer1 invalidate];
        self.timer1 = nil;
        self.count1 = 0;
        self.imageView2.image = [UIImage imageNamed:@"login_bg_2"];
        [UIView animateWithDuration:2 animations:^{
            self.imageView1.alpha = 0;
            self.imageView2.alpha = 1;
        } completion:^(BOOL finished) {
            [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(imageView2AnimationStart) userInfo:nil repeats:NO];
        }];
    }
}

动画过渡

在第一张图片模糊到一定程度时,对其做渐变处理,改变其alpha值(从1到0),同时让第二张图显现出来(从1到0)。至此,整个动画就基本完成了。

另外

需要对其他方面做些优化,比如NSTimer的开启与暂停,以及切换到其他页面后需要关闭定时器等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,242评论 25 708
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,229评论 4 61
  • 文&图 | 小猪 一直相信真正爱吃的人,即使再懒也总是会愿意自己倒腾点吃的。 毕竟餐厅不总是好吃,外卖不总是放心,...
    猫小猪阅读 594评论 0 7
  • 无意中问了你,感觉现在和以前不一样了,以前有什么聊什么。现在呢,没有那种感觉了。你哈哈回答到:以前是你傻,我陪你一...
    我今年22岁阅读 633评论 0 1
  • ——谈时间管理 小时候,喜欢听罗大佑唱《光阴的日子》,对流水一般的光阴,几多怀念,几多无奈,流光美好且无情,既然无...
    emma佳小佳阅读 180评论 0 0