当前位置: > > > Swift - 使用CIPixellate给图片打码(全图马赛克,部分区域马赛克)

Swift - 使用CIPixellate给图片打码(全图马赛克,部分区域马赛克)

通过使用CIPixellate滤镜,可以很方便使图片像素化。从而实现马赛克效果,既可以将整个图片打码,也可以只选择部分区域打码。

 1,代码说明
(1)CIPixellate通过设置inputScale参数,可以修改马赛克大小。最小值为1,数字越大马赛克就越大。
(2)全图马赛克很简单,只需要给图片使用像素化滤镜即可。
(3)部分区域打码的话,需要创建三个CIImage。分别是全图打码的CIImage,原图CIImage,蒙板CIImage。然后使用CIBlendWithMask滤镜来混合三者。

2,效果图如下
从上到下分别是原图,全图打码,区域打码。(其中区域打码设置了inputScale更改马赛克大小,全图为默认值)



3,代码如下:
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    //原图
    lazy var originalImage: UIImage = {
        return UIImage(named: "m1.jpg")
        }()!
    
    lazy var context: CIContext = {
        return CIContext(options: nil)
        }()

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    //恢复原图
    @IBAction func resetImg(sender: AnyObject) {
        imageView.image = originalImage
    }
    
    //全图马赛克
    @IBAction func pixAll(sender: AnyObject) {
        let filter = CIFilter(name: "CIPixellate")!
        let inputImage = CIImage(image: originalImage)
        filter.setValue(inputImage, forKey: kCIInputImageKey)
        //filter.setValue(25, forKey: kCIInputScaleKey) //值越大马赛克就越大(使用默认)
        let fullPixellatedImage = filter.outputImage
        
        let cgImage = context.createCGImage(fullPixellatedImage!,
            fromRect: fullPixellatedImage!.extent)
        imageView.image = UIImage(CGImage: cgImage)
    }
    
    //部分区域马赛克
    @IBAction func pixArea(sender: AnyObject) {
        //马赛克全图
        let filter = CIFilter(name: "CIPixellate")!
        let inputImage = CIImage(image: originalImage)!
        filter.setValue(inputImage, forKey: kCIInputImageKey)
        filter.setValue(22, forKey: kCIInputScaleKey) //值越大马赛克就越大
        let fullPixellatedImage = filter.outputImage
        
        //蒙板创建
        var maskImage: CIImage
        //第一个打码区域(中间大圆)
        var centerX = inputImage.extent.size.width / 2
        let centerY = inputImage.extent.size.height / 2
        var radius = min(inputImage.extent.size.width/3, inputImage.extent.size.height/3)
        var temp = createMaskImage(inputImage.extent, centerX: centerX, centerY: centerY,
            radius: radius)
        maskImage = temp
        //第二个打码区域(左边小圆)
        centerX = inputImage.extent.size.width / 6
        radius = min(inputImage.extent.size.width/4, inputImage.extent.size.height/5)
        temp = createMaskImage(inputImage.extent, centerX: centerX, centerY: centerY,
            radius: radius)
        maskImage = CIFilter(name: "CISourceOverCompositing",
            withInputParameters: [
                kCIInputImageKey : temp,
                kCIInputBackgroundImageKey : maskImage
            ])!.outputImage!
        
        //混合图像输出
        let blendFilter = CIFilter(name: "CIBlendWithMask")!
        blendFilter.setValue(fullPixellatedImage, forKey: kCIInputImageKey)
        blendFilter.setValue(inputImage, forKey: kCIInputBackgroundImageKey)
        blendFilter.setValue(maskImage, forKey: kCIInputMaskImageKey)

        let blendOutputImage = blendFilter.outputImage
        let blendCGImage = context.createCGImage(blendOutputImage!,
            fromRect: blendOutputImage!.extent)
        imageView.image = UIImage(CGImage: blendCGImage)

    }
    
    //创建打码区域
    func createMaskImage(rect: CGRect ,centerX: CGFloat, centerY: CGFloat, radius:CGFloat)
        -> CIImage{
        let radialGradient = CIFilter(name: "CIRadialGradient",
            withInputParameters: [
                "inputRadius0" : radius,
                "inputRadius1" : radius + 1,
                "inputColor0" : CIColor(red: 0, green: 1, blue: 0, alpha: 1),
                "inputColor1" : CIColor(red: 0, green: 0, blue: 0, alpha: 0),
                kCIInputCenterKey : CIVector(x: centerX, y: centerY)
            ])
        let radialGradientOutputImage = radialGradient!.outputImage!.imageByCroppingToRect(rect)
        return radialGradientOutputImage
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
}
评论0