Camera and editor improvements

This commit is contained in:
Ilya Laktyushin
2023-05-26 17:32:02 +04:00
parent d086a8f674
commit eeb1c469f3
64 changed files with 4037 additions and 1108 deletions

View File

@@ -3,45 +3,57 @@ import AVFoundation
import Metal
import MetalKit
import Display
import Accelerate
func loadTexture(image: UIImage, device: MTLDevice) -> MTLTexture? {
func dataForImage(_ image: UIImage) -> UnsafeMutablePointer<UInt8> {
let imageRef = image.cgImage
let width = Int(image.size.width)
let height = Int(image.size.height)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let rawData = UnsafeMutablePointer<UInt8>.allocate(capacity: width * height * 4)
let bytePerPixel = 4
let bytesPerRow = bytePerPixel * Int(width)
let bitsPerComponent = 8
let bitmapInfo = CGBitmapInfo.byteOrder32Little.rawValue + CGImageAlphaInfo.premultipliedFirst.rawValue
let context = CGContext.init(data: rawData, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)
context?.draw(imageRef!, in: CGRect(x: 0, y: 0, width: width, height: height))
return rawData
}
let width = Int(image.size.width * image.scale)
let height = Int(image.size.height * image.scale)
let bytePerPixel = 4
let bytesPerRow = bytePerPixel * width
var texture : MTLTexture?
let region = MTLRegionMake2D(0, 0, Int(width), Int(height))
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm, width: width, height: height, mipmapped: false)
texture = device.makeTexture(descriptor: textureDescriptor)
let data = dataForImage(image)
texture?.replace(region: region, mipmapLevel: 0, withBytes: data, bytesPerRow: bytesPerRow)
return texture
}
final class ImageTextureSource: TextureSource {
weak var output: TextureConsumer?
var textureLoader: MTKTextureLoader?
var texture: MTLTexture?
init(image: UIImage, renderTarget: RenderTarget) {
guard let device = renderTarget.mtlDevice, var cgImage = image.cgImage else {
return
if let device = renderTarget.mtlDevice {
self.texture = loadTexture(image: image, device: device)
}
let textureLoader = MTKTextureLoader(device: device)
self.textureLoader = textureLoader
if let bitsPerPixel = image.cgImage?.bitsPerPixel, bitsPerPixel > 32 {
let updatedImage = generateImage(image.size, contextGenerator: { size, context in
context.setFillColor(UIColor.black.cgColor)
context.fill(CGRect(origin: .zero, size: size))
context.draw(cgImage, in: CGRect(origin: .zero, size: size))
}, opaque: false)
cgImage = updatedImage?.cgImage ?? cgImage
}
self.texture = try? textureLoader.newTexture(cgImage: cgImage, options: [.SRGB : false])
}
func start() {
}
func pause() {
}
func connect(to consumer: TextureConsumer) {
self.output = consumer
if let texture = self.texture {
self.output?.consumeTexture(texture, rotation: .rotate0Degrees)
self.output?.consumeTexture(texture)
}
}
}
@@ -59,3 +71,17 @@ func pixelBufferToMTLTexture(pixelBuffer: CVPixelBuffer, textureCache: CVMetalTe
return nil
}
func getTextureImage(device: MTLDevice, texture: MTLTexture) -> UIImage? {
let colorSpace = CGColorSpaceCreateDeviceRGB()
let context = CIContext(mtlDevice: device, options: [:])
guard var ciImage = CIImage(mtlTexture: texture, options: [.colorSpace: colorSpace]) else {
return nil
}
let transform = CGAffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, ciImage.extent.height)
ciImage = ciImage.transformed(by: transform)
guard let cgImage = context.createCGImage(ciImage, from: CGRect(origin: .zero, size: CGSize(width: ciImage.extent.width, height: ciImage.extent.height))) else {
return nil
}
return UIImage(cgImage: cgImage)
}