Created
September 28, 2015 05:32
-
-
Save muukii/fbb523538e14bc4c75a2 to your computer and use it in GitHub Desktop.
CIImageView (Using Metal)
This file contains hidden or 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
// | |
// MTKCIImageView.swift | |
// Fil | |
// | |
// Created by Muukii on 9/27/15. | |
// Copyright © 2015 muukii. All rights reserved. | |
// | |
import Foundation | |
import Metal | |
import MetalKit | |
class MTKCIImageView: MTKView { | |
var image: CIImage? { | |
didSet { | |
self.draw() | |
} | |
} | |
var originalImageExtent: CGRect = CGRect.zero { | |
didSet { | |
} | |
} | |
var scale: CGFloat { | |
return max(self.frame.width / originalImageExtent.width, self.frame.height / originalImageExtent.height) | |
} | |
func update() { | |
guard let img = image where destRect.size.width <= img.extent.size.width && destRect.size.height <= img.extent.size.height else { | |
return | |
} | |
self.draw() | |
} | |
let context: CIContext | |
let commandQueue: MTLCommandQueue | |
convenience init(frame: CGRect) { | |
let device = MTLCreateSystemDefaultDevice() | |
self.init(frame: frame, device: device) | |
} | |
override init(frame frameRect: CGRect, device: MTLDevice?) { | |
guard let device = device else { | |
fatalError("Can't use Metal") | |
} | |
commandQueue = device.newCommandQueueWithMaxCommandBufferCount(5) | |
context = CIContext(MTLDevice: device, options: [kCIContextUseSoftwareRenderer:false]) | |
super.init(frame: frameRect, device: device) | |
self.framebufferOnly = false | |
self.enableSetNeedsDisplay = false | |
self.paused = true | |
self.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0) | |
} | |
required init(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func drawRect(rect: CGRect) { | |
JEDump(rect, "Draw Use Metal") | |
guard let image = self.image else { | |
return | |
} | |
let dRect = destRect | |
let drawImage: CIImage | |
if dRect == image.extent { | |
drawImage = image | |
} else { | |
let scale = max(dRect.height / image.extent.height, dRect.width / image.extent.width) | |
drawImage = image.imageByApplyingTransform(CGAffineTransformMakeScale(scale, scale)) | |
} | |
let commandBuffer = commandQueue.commandBufferWithUnretainedReferences() | |
guard let texture = self.currentDrawable?.texture else { | |
return | |
} | |
guard let colorSpace = drawImage.colorSpace ?? CGColorSpaceCreateDeviceRGB() else { | |
return | |
} | |
context.render(drawImage, toMTLTexture: texture, commandBuffer: commandBuffer, bounds: dRect, colorSpace: colorSpace) | |
commandBuffer.presentDrawable(self.currentDrawable!) | |
commandBuffer.commit() | |
} | |
private var destRect: CGRect { | |
let scale: CGFloat | |
if UIScreen.mainScreen().scale == 3 { | |
// BUG? | |
scale = 2.0 * (2.0 / UIScreen.mainScreen().scale) * 2 | |
} else { | |
scale = UIScreen.mainScreen().scale | |
} | |
let destRect = CGRectApplyAffineTransform(self.bounds, CGAffineTransformMakeScale(scale, scale)) | |
return destRect | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, i get orientation and flip issue in simulator. same like: https://stackoverflow.com/questions/60164536/flipped-picture-after-render-in-metal