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



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



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() } }