-
-
Save ericleiyang/b0414e284db7e17e918d42ce5403e185 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import CoreImage | |
import Metal | |
import MetalKit | |
class ViewController: UIViewController { | |
@IBOutlet weak var imageView: UIImageView! | |
@IBOutlet weak var mtkView: MTKView! | |
// Metal resources | |
var device: MTLDevice! | |
var commandQueue: MTLCommandQueue! | |
var sourceTexture: MTLTexture! | |
// Core Image resources | |
var context: CIContext! | |
let filter = CIFilter(name: "CIGaussianBlur")! | |
let colorSpace = CGColorSpaceCreateDeviceRGB() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Do any additional setup after loading the view. | |
// UIBlurEffect | |
let blurEffect = UIBlurEffect(style: .light) | |
let blurEffectView = UIVisualEffectView() | |
blurEffectView.frame = CGRect(x: 0, y: 0, width: imageView.frame.width, height: 400) | |
blurEffectView.center = imageView.center | |
self.imageView.addSubview(blurEffectView) | |
UIView.animate(withDuration: 5) { | |
blurEffectView.effect = blurEffect | |
} | |
// CIFilter | |
let blurredRect = CGRect(x: 0, | |
y: imageView.center.y - 200, | |
width: imageView.frame.width, | |
height: 400) | |
let context = CIContext() | |
imageView.image = imageView.image?.blurredImage(with: context, | |
radius: 20, | |
atRect: blurredRect) | |
// Metal | |
device = MTLCreateSystemDefaultDevice() | |
commandQueue = device.makeCommandQueue() | |
let textureLoader = MTKTextureLoader(device: device) | |
sourceTexture = try! textureLoader.newTexture(cgImage: UIImage(named: "street.png")!.cgImage!) | |
let view = self.mtkView! | |
view.delegate = self | |
view.device = device | |
view.framebufferOnly = false | |
context = CIContext(mtlDevice: device) | |
} | |
} | |
extension ViewController: MTKViewDelegate { | |
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { | |
} | |
func draw(in view: MTKView) { | |
if let currentDrawable = view.currentDrawable, | |
let commandBuffer = commandQueue.makeCommandBuffer() { | |
let inputImage = CIImage(mtlTexture: sourceTexture)!.oriented(.down) | |
filter.setValue(inputImage, forKey: kCIInputImageKey) | |
filter.setValue(10.0, forKey: kCIInputRadiusKey) | |
context.render(filter.outputImage!, | |
to: currentDrawable.texture, | |
commandBuffer: commandBuffer, | |
bounds: mtkView.bounds, | |
colorSpace: colorSpace) | |
commandBuffer.present(currentDrawable) | |
commandBuffer.commit() | |
} | |
} | |
} | |
extension UIImage { | |
func blurredImage(with context: CIContext, radius: CGFloat, atRect: CGRect) -> UIImage? { | |
guard let ciImg = CIImage(image: self) else { return nil } | |
let cropedCiImg = ciImg.cropped(to: atRect) | |
let blur = CIFilter(name: "CIGaussianBlur") | |
blur?.setValue(cropedCiImg, forKey: kCIInputImageKey) | |
blur?.setValue(radius, forKey: kCIInputRadiusKey) | |
if let ciImgWithBlurredRect = blur?.outputImage?.composited(over: ciImg), | |
let outputImg = context.createCGImage(ciImgWithBlurredRect, from: ciImgWithBlurredRect.extent) { | |
return UIImage(cgImage: outputImg) | |
} | |
return nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment