Swift - 使用CIPixellate给图片打码(全图马赛克,部分区域马赛克)
作者:hangge | 2015-10-22 09:46
通过使用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()
}
}
全部评论(0)