CIFilter濾鏡&UIImagePickerController 從相簿與相機取圖片

Camera要實機才能測試

協定UIImagePickerControllerDelegate,UINavigationControllerDelegate
import CoreImage.CIFilterBuiltins
CIContext()
CIFilter()
UIImagePickerController.isSourceTypeAvailable(.photoLibrary)
UIImagePickerController()
UIImagePickerController.sourceType
UIImagePickerController.delegate
info
CIImage.oriented
CIImageToCGImage
present
UIImageWriteToSavedPhotosAlbum
Privacy — Photo Library Additions Usage Description
Privacy — Camera Usage Description

import UIKitimport CoreImage.CIFilterBuiltinsclass ViewController: UIViewController ,UIImagePickerControllerDelegate,UINavigationControllerDelegate{
@IBOutlet var valueLabel: [UILabel]!@IBOutlet var steppers: [UIStepper]!@IBOutlet weak var imageView: UIImageView!@IBOutlet var sliders: [UISlider]!var ciImage: CIImage? //從相簿選照片後,從UIImage轉成CIImage並存起來用let ciContext = CIContext() // ciImage轉cgImage需要用的
override func viewDidLoad() {super.viewDidLoad()imageView.image = UIImage(named: "風景圖")!//將一開始預設的圖片,轉成ciImage存起來ciImage = CIImage(image: UIImage(named: "風景圖")!)//將Slider與Stepper的最大最小值統一for i in 0...6 {setTheValue(slider: sliders[i], stepper: steppers[i])}//給每個Slider與Stepper標籤,並將顯示數值的Label取到小數第一位for i in 0...6 {steppers[i].tag = isliders[i].tag = ivalueLabel[i].text = String(format: "%.1f", sliders[i].value)}}
func setTheValue(slider:UISlider , stepper:UIStepper){stepper.minimumValue = Double(slider.minimumValue)stepper.maximumValue = Double(slider.maximumValue)stepper.value = Double(slider.value)}

各式濾鏡方法

func makeCIFilterMonochrome(ciImage:CIImage,red:Float,green:Float,blue:Float) -> CIImage {
let ciFilter = CIFilter.colorMonochrome()
ciFilter.intensity = sliders[0].value
ciFilter.inputImage = ciImage
ciFilter.color = CIColor(red: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue))
return ciFilter.outputImage!
}

func makeCIFilterInstant(ciImage:CIImage) -> CIImage {
let ciFilterInstant = CIFilter.photoEffectInstant()
ciFilterInstant.inputImage = ciImage
return ciFilterInstant.outputImage!

}

func makeCIFilterNoir(ciImage:CIImage) -> CIImage {
let ciFilterNoir = CIFilter.photoEffectNoir()
ciFilterNoir.inputImage = ciImage
return ciFilterNoir.outputImage!
}

func makeCIFilterTonal(ciImage:CIImage) -> CIImage {
let ciFilterTonal = CIFilter.photoEffectTonal()
ciFilterTonal.inputImage = ciImage
return ciFilterTonal.outputImage!
}

func makeCIFilterTransfer(ciImage:CIImage) -> CIImage {
let ciFilterTransfer = CIFilter.photoEffectTransfer()
ciFilterTransfer.inputImage = ciImage
return ciFilterTransfer.outputImage!
}

func makeCIFilterMono(ciImage:CIImage) -> CIImage {
let ciFilterMono = CIFilter.photoEffectMono()
ciFilterMono.inputImage = ciImage
return ciFilterMono.outputImage!
}

func makeCIFilterFade(ciImage:CIImage) -> CIImage {
let ciFilterFade = CIFilter.photoEffectFade()
ciFilterFade.inputImage = ciImage
return ciFilterFade.outputImage!
}

func makeCIFilterProcess(ciImage:CIImage) -> CIImage {
let ciFilterProcess = CIFilter.photoEffectProcess()
ciFilterProcess.inputImage = ciImage
return ciFilterProcess.outputImage!
}

func makeCIFilterChrome(ciImage:CIImage) -> CIImage {
let ciFilterChrome = CIFilter.photoEffectChrome()
ciFilterChrome.inputImage = ciImage
return ciFilterChrome.outputImage!
}

func makeCIFilterEdgeWork(ciImage:CIImage,radius:Float) -> CIImage {
let ciFilterEdgeWork = CIFilter.edgeWork()
ciFilterEdgeWork.radius = radius
//ciFilterEdgeWork.inputImage = ciImage //會閃退有bug
ciFilterEdgeWork.setValue(ciImage, forKey: kCIInputImageKey)
return ciFilterEdgeWork.outputImage!
}

func makeCIFilterColorInvert(ciImage:CIImage) -> CIImage {
let ciFilterColorInvert = CIFilter.colorInvert()
ciFilterColorInvert.inputImage = ciImage
return ciFilterColorInvert.outputImage!
}

func makeCIFilterColorControls(ciImage:CIImage) -> CIImage {
let ciFilterColorControls = CIFilter.colorControls()
ciFilterColorControls.brightness = sliders[1].value
ciFilterColorControls.contrast = sliders[2].value
ciFilterColorControls.saturation = sliders[3].value
ciFilterColorControls.inputImage = ciImage
return ciFilterColorControls.outputImage!
}

func makeCIFilterComicEffect(ciImage:CIImage) -> CIImage {
let ciFilterComicEffect = CIFilter.comicEffect()
//ciFilterComicEffect.inputImage = ciImage //會閃退有bug
ciFilterComicEffect.setValue(ciImage, forKey: kCIInputImageKey)
return ciFilterComicEffect.outputImage!
}

func makeCIFilterVignetteEffect(ciImage:CIImage,falloff:Float,intensity:Float,radius:Float,x:CGFloat,y:CGFloat) -> CIImage {
let ciFilterVignetteEffect = CIFilter.vignetteEffect()
ciFilterVignetteEffect.falloff = falloff
ciFilterVignetteEffect.intensity = intensity
ciFilterVignetteEffect.radius = radius
ciFilterVignetteEffect.center = CGPoint(x: x, y: y)
ciFilterVignetteEffect.inputImage = ciImage
return ciFilterVignetteEffect.outputImage!
}

各式濾鏡按鈕

@IBAction func instantButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterInstant(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func noirButtonClick(_ sender: Any) {

let outPutCIimage = makeCIFilterNoir(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIimage)
}

@IBAction func tronalButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterTonal(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func transferButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterTransfer(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func monoButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterMono(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func fadeButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterFade(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func processButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterProcess(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func chromeButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterChrome(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func edgeWorkButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterEdgeWork(ciImage: ciImage!, radius: 10)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func InvertButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterColorInvert(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func edgeInvertButtonClick(_ sender: Any) {

var outPutCIImage = makeCIFilterEdgeWork(ciImage: ciImage!, radius: 10)

outPutCIImage = makeCIFilterColorInvert(ciImage: outPutCIImage)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func comicButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterComicEffect(ciImage: ciImage!)

imageView.image = UIImage(ciImage: outPutCIImage)
}

@IBAction func vignetteButtonClick(_ sender: Any) {

let outPutCIImage = makeCIFilterVignetteEffect(ciImage: ciImage!, falloff: 0, intensity: 0.5, radius: 300, x: 1000, y: 500)

imageView.image = UIImage.init(ciImage: outPutCIImage)
}
@IBAction func sliderChange(_ sender: UISlider) {

var outPutCIImage = ciImage //避免更改全域變數的ciImage,先另存起來用,不然濾鏡效果會一直疊加上去

outPutCIImage = makeCIFilterMonochrome(ciImage: outPutCIImage!, red: sliders[4].value, green: sliders[5].value, blue: sliders[6].value)
outPutCIImage = makeCIFilterColorControls(ciImage: outPutCIImage!)

imageView.image = UIImage(ciImage: outPutCIImage!)

steppers[sender.tag].value = Double(sender.value)

valueLabel[sender.tag].text = String(format: "%.1f", sender.value)


}
@IBAction func stepperChange(_ sender: UIStepper) {

var outPutCIImage = ciImage

outPutCIImage = makeCIFilterMonochrome(ciImage: outPutCIImage!, red: sliders[4].value, green: sliders[5].value, blue: sliders[6].value)

outPutCIImage = makeCIFilterColorControls(ciImage: outPutCIImage!)

imageView.image = UIImage(ciImage: outPutCIImage!)

sliders[sender.tag].value = Float(sender.value)
valueLabel[sender.tag].text = String(format: "%.1f", sender.value)

}
@IBAction func selectPicture(_ sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) == true {

let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary //資料類型為 相簿
imagePickerController.delegate = self //代表為自己

//顯示各種Controller的present,相簿才會跳出來(影片也可用present AVPlayerController
present(imagePickerController, animated: true, completion: nil)

imagePickerController.allowsEditing = true //准許編輯

}

}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {let originalImage = info[.originalImage] as? UIImage //原始照
imageView.image = originalImage//將從相簿選的原始UIImage轉成CIImage用全域變數存起來,給其他濾鏡button使用ciImage = CIImage(image: originalImage!)//將ciImage定向,避免之後使用或套濾鏡時轉向,搭配自建extension的swift檔案ciImage = ciImage?.oriented(CGImagePropertyOrientation(originalImage!.imageOrientation))//如果資料類型為 相機 則拍照的圖片存到相簿,要設定權限NSPhotoLibraryAddUsageDescriptionif picker.sourceType == .camera {UIImageWriteToSavedPhotosAlbum(originalImage!, nil, nil, nil)}//選完照片後從顯示的controller回到前一頁dismiss(animated: true, completion: nil)}
@IBAction func takePhoto(_ sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(.camera) == true {

let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .camera
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)

}
}
@IBAction func imageSave(_ sender: UIButton) {

let imageCIImage = imageView.image?.ciImage
var cgImage = imageView.image?.cgImage
var uiImage:UIImage?

if imageCIImage != nil {
cgImage = ciContext.createCGImage(imageCIImage!, from: imageCIImage!.extent)
}

uiImage = UIImage(cgImage: cgImage!)

UIImageWriteToSavedPhotosAlbum(uiImage!, nil, nil, nil)


}

--

--