CoreImage proporciona procesamiento de imágenes, reconocimiento facial, mejora de imágenes, filtros de imágenes y transiciones de imágenes. Los datos que opera provienen de Core Graphics, Core Video, Image IO y usa CPU o GPU para renderizar. CoreImage encapsula la implementación subyacente y proporciona una API fácil de usar para la capa superior.
1. Marco CoreImage
El marco CoreImage se divide en: capa de representación, capa de procesamiento, capa API. Entre ellos, la capa de procesamiento incluye procesamiento de GPU (OpenGL y Metal), procesamiento de CPU (Grand Central Dispatch); la capa de procesamiento incluye filtros integrados; la capa de API incluye Core Graphics, Core Video e Image IO. Como se muestra abajo:
2. Procesamiento de imágenes
1. Flujo de procesamiento de imágenes
El procesamiento de imágenes incluye principalmente tres clases: CIContext, CIFilter, CIImage. Un ejemplo del flujo de procesamiento es el siguiente:
import CoreImage
// 1、创建CIContext
let context = CIContext()
// 2、创建CIFilter
let filter = CIFilter(name: "CISepiaTone")!
filter.setValue(0.8, forKey: kCIInputIntensityKey)
// 3、创建CIImage
let image = CIImage(contentsOfURL: mURL)
// 4、image应用到filter滤镜
filter.setValue(image, forKey: kCIInputImageKey)
let result = filter.outputImage!
// 5、使用context创建CGImage(用于管理image以及对象复用)
let cgImage = context.createCGImage(result, from: result.extent)
// 6、显示滤镜结果
imageView.image = UIImage(CIImage: result)
2. Tipo de datos de imagen
La imagen se utiliza como filtro de entrada y salida, incluidos los siguientes tipos de datos:
URL del archivo de imagen o NSData de los datos de imagen;
Objetos CGImageRef, UIImage, NSBitmapImageRep;
Metal, textura OpenGl;
CVImageBufferRef、CVPixelBufferRef;
IOSurfaceRef que comparte datos entre procesos;
Datos de mapa de bits de memoria o CIImageProvider;
3. Crear cadena de filtros
La creación de la cadena de filtros Filter Chain, el código de ejemplo es el siguiente:
func applyFilterChain(to image: CIImage) -> CIImage {
// 创建CIFilter,并且设置color滤镜
let colorFilter = CIFilter(name: "CIPhotoEffectProcess", withInputParameters:
[kCIInputImageKey: image])!
// 应用bloom滤镜
let bloomImage = colorFilter.outputImage!.applyingFilter("CIBloom",
withInputParameters: [
kCIInputRadiusKey: 10.0,
kCIInputIntensityKey: 1.0
])
// 图像裁剪
let cropRect = CGRect(x: 350, y: 350, width: 150, height: 150)
let croppedImage = bloomImage.cropping(to: cropRect)
return croppedImage
}
4. Aplicar filtros al video
Tome el filtro de desenfoque gaussiano aplicado al video como ejemplo, el código relevante es el siguiente:
// 创建高斯模糊filter
let filter = CIFilter(name: "CIGaussianBlur")!
let composition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request in
let source = request.sourceImage.clampingToExtent()
filter.setValue(source, forKey: kCIInputImageKey)
// 根据时间戳设置模糊系数
let seconds = CMTimeGetSeconds(request.compositionTime)
filter.setValue(seconds * 10.0, forKey: kCIInputRadiusKey)
// 裁剪
let output = filter.outputImage!.cropping(to: request.sourceImage.extent)
// 应用滤镜结果到视频
request.finish(with: output, context: nil)
})
5. Usa filtros metálicos en tiempo real
Primero cree una vista de Metal para la representación de imágenes:
class ViewController: UIViewController, MTKViewDelegate {
// Metal设备、纹理、队列
var device: MTLDevice!
var commandQueue: MTLCommandQueue!
var sourceTexture: MTLTexture!
// 高斯模糊
var context: CIContext!
let filter = CIFilter(name: "CIGaussianBlur")!
let colorSpace = CGColorSpaceCreateDeviceRGB()
override func viewDidLoad() {
super.viewDidLoad()
// 创建设备、命令队列
device = MTLCreateSystemDefaultDevice()
commandQueue = device.newCommandQueue()
let view = self.view as! MTKView
view.delegate = self
view.device = device
view.framebufferOnly = false
// 创建CIContext
context = CIContext(mtlDevice: device)
}
}
El proceso de representación del filtro en tiempo real, el código de muestra es el siguiente:
public func draw(in view: MTKView) {
if let currentDrawable = view.currentDrawable {
let commandBuffer = commandQueue.commandBuffer()
// 1、使用纹理创建UIImage,并且进行滤镜
let inputImage = CIImage(mtlTexture: sourceTexture)!
filter.setValue(inputImage, forKey: kCIInputImageKey)
filter.setValue(20.0, forKey: kCIInputRadiusKey)
// 2、使用context进行渲染
context.render(filter.outputImage!,
to: currentDrawable.texture,
commandBuffer: commandBuffer,
bounds: inputImage.extent,
colorSpace: colorSpace)
// 3、使用buffer显示结果
commandBuffer.present(currentDrawable)
commandBuffer.commit()
}
}
3. Reconocimiento facial
iOS proporciona CIDetector para el reconocimiento facial, el código de muestra es el siguiente:
// 1、创建CIContext
CIContext *context = [CIContext context];
// 2、创建options,指定识别精度
NSDictionary *opts = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
// 3、创建检测器,指定识别类型
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
context:context
options:opts];
// 4、指定图像方向
opts = @{ CIDetectorImageOrientation :
[[mImage properties] valueForKey:kCGImagePropertyOrientation] };
// 5、获取识别结果
NSArray *features = [detector featuresInImage:mImage options:opts];
Los resultados del reconocimiento facial incluyen: la posición del ojo izquierdo, el ojo derecho y la boca. Los resultados se juzgan de la siguiente manera:
for (CIFaceFeature *f in features) {
NSLog(@"%@", NSStringFromRect(f.bounds));
if (f.hasLeftEyePosition) {
NSLog(@"Left eye x=%g y=%g", f.leftEyePosition.x, f.leftEyePosition.y);
}
if (f.hasRightEyePosition) {
NSLog(@"Right eye x=%g y=%g", f.rightEyePosition.x, f.rightEyePosition.y);
}
if (f.hasMouthPosition) {
NSLog(@"Mouth x=%g y=%g", f.mouthPosition.x, f.mouthPosition.y);
}
}
Echemos un vistazo al efecto de reconocimiento facial:
4. Mejora de la imagen
Las mejoras de imagen proporcionadas por iOS incluyen: corrección de ojos rojos, equilibrio facial, mejora de color y resaltado de sombras, como se muestra en la siguiente tabla:
Filtrar | describir |
CIRedOjoCorrección | Arreglar los ojos rojos causados por el flash de la cámara |
CIFaceBalance | Ajustar el color de la cara según el tono de piel |
CIVibrance | Mejorar la saturación |
CITonoCurva | ajustar el contraste |
CIHighlightShadowAdjust | Ajustar detalle de sombra |
Un ejemplo de uso del aumento de imagen es el siguiente:
NSDictionary *options = @{ CIDetectorImageOrientation :
[[image properties] valueForKey:kCGImagePropertyOrientation] };
NSArray *adjustments = [image autoAdjustmentFiltersWithOptions:options];
for (CIFilter *filter in adjustments) {
[filter setValue:image forKey:kCIInputImageKey];
myImage = filter.outputImage;
}