iOS图片处理之背景虚化原理解析


iOS图片处理之背景虚化原理解析_第1张图片


背景虚化就是焦点中心区域清晰,中心到外部逐渐虚化的一种效果。

实现原理,由上到下分三层,最下面一层为原图

3- 遮罩层(径向渐变)

2- 原图高斯模糊后的效果图

1- 原图

根据遮罩原理,图层2的alpha值取自图层3遮罩层的alpha,遮罩层通过径向渐变的绘制,可实现中心区域透明度为1,中心到外部透明度逐渐降为0的效果。

遮罩层绘制代码如下:

override func drawRect(rect: CGRect)
    {
        //print("drawRect: context", radius, rect)
        guard let context = UIGraphicsGetCurrentContext() else{
            return
        }
        
        var gradient: CGGradientRef?
        var colorSpace: CGColorSpaceRef?
        
        let red:CGFloat = 1
        let green:CGFloat = 1
        let blue:CGFloat = 1
        
        
        let locations: [CGFloat] = [0.0, innerRadius / radius, (innerRadius + gradientWidth) / radius, 1.0]
        let numberOfLocation: size_t = locations.count
        let components: [CGFloat] = [
                                     red,   green,  blue,   0.0,
                                     red,   green,  blue,   0.0,
                                     red,   green,  blue,   1.0,
                                     red,   green,  blue,   1.0]
        
        colorSpace = CGColorSpaceCreateDeviceRGB()
        gradient = CGGradientCreateWithColorComponents(colorSpace,
                                                       components,
                                                       locations,
                                                       numberOfLocation)
        //定义起始点和终止点
        let startPoint: CGPoint = CGPointMake(radius, radius)
        let endPoint: CGPoint = CGPointMake(radius, radius)
        
        CGContextDrawRadialGradient(context,
                                    gradient,
                                    startPoint,
                                    0,
                                    endPoint,
                                    radius,
                                    CGGradientDrawingOptions(rawValue: 0))
    }


线性渐变遮罩层代码如下:

override func drawRect(rect: CGRect)
    {
        
        guard let context = UIGraphicsGetCurrentContext() else{
            return
        }
        
        var gradient: CGGradientRef?
        var colorSpace: CGColorSpaceRef?
        
        let red:CGFloat = 1
        let green:CGFloat = 1
        let blue:CGFloat = 1
        
        let frameWidth:CGFloat = _originSize.width
        let p1 = (frameWidth * 0.5 - innerWidth * 0.5 - gradientWidth) / frameWidth
        let p2 = (frameWidth * 0.5 - innerWidth * 0.5) / frameWidth
        let p3 = (frameWidth * 0.5 + innerWidth * 0.5) / frameWidth
        let p4 = (frameWidth * 0.5 + innerWidth * 0.5 + gradientWidth) / frameWidth
        let locations: [CGFloat] = [0.0, p1, p2, p3, p4, 1.0]
        let numberOfLocation: size_t = locations.count
        let components: [CGFloat] = [
            red,   green,  blue,   1.0,
            red,   green,  blue,   1.0,
            red,   green,  blue,   0.0,
            red,   green,  blue,   0.0,
            red,   green,  blue,   1.0,
            red,   green,  blue,   1.0
            ]
        
        colorSpace = CGColorSpaceCreateDeviceRGB()
        gradient = CGGradientCreateWithColorComponents(colorSpace,
                                                       components,
                                                       locations,
                                                       numberOfLocation)

        let startPoint: CGPoint = CGPointMake(0, 0)
        let endPoint: CGPoint = CGPointMake(0, frameWidth)
        
        
        CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions(rawValue: 0))
        
    }



遮罩层的移动、缩放、旋转手势需要同时运行

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool
    {
        return true
    }

另外为了避免遮罩层缩放、旋转过程中的卡顿,因此需要将遮罩层重绘异步执行

xxx.layer.drawsAsynchronously = true








你可能感兴趣的:(swift)