CoreImage es un framework de Apple para el procesamiento de imágenes y video en tiempo real, que proporciona docenas de CIFilter integrados para corrección de color, desenfoque, superposición de texturas y detección. Según la Documentación de Apple, CoreImage utiliza la GPU para el procesamiento de píxeles de alto rendimiento en dispositivos iOS. El framework admite CIImage como un objeto de imagen inmutable y cadenas de filtros para componer efectos sin pérdida de calidad.
Puntos clave
CoreImage es un framework de Apple para el procesamiento de imágenes rasterizadas y video, presentado por primera vez en macOS 10.4 Tiger y portado a iOS 5.0. A diferencia de Core Graphics o UIKit, CoreImage funciona a nivel de shaders de píxeles, utilizando la GPU para cálculos paralelos. Esto permite aplicar efectos complejos — desenfoque, corrección de color, morphing — a imágenes de resolución de megapíxeles en milisegundos.
La arquitectura de CoreImage se basa en el concepto de evaluación perezosa (lazy evaluation): CIFilter no realiza procesamiento hasta el momento de renderizado en CIContext. El desarrollador construye una cadena de múltiples CIFilter, conectando la salida de un filtro con la entrada de otro, y solo la llamada a render inicia el pipeline completo de la GPU. Esto minimiza la cantidad de pases a través de la tarjeta gráfica y mantiene el rendimiento.
CoreImage soporta amplia gama de colores (P3, sRGB, sRGB lineal), imágenes HDR y trabajo con formatos de píxeles de 16 y 32 bits. En dispositivos con Neural Engine, CoreImage puede combinar shaders de GPU con Core ML para procesamiento inteligente — por ejemplo, corrección automática de color basada en aprendizaje automático, como se implementa en la aplicación Fotos en iOS 17.
Tres clases principales forman el núcleo de CoreImage: CIImage (datos), CIFilter (operación) y CIContext (entorno de ejecución). Cada clase es responsable de su propia fase del pipeline y no mezcla responsabilidades.
CIImage es un objeto ligero que describe una imagen pero no contiene datos de píxeles directamente. Puede crearse a partir de UIImage, CGImage, textura Metal, textura GL o un archivo en disco. CIImage es inmutable — cualquier aplicación de filtro crea un nuevo CIImage sin modificar el original. Esto permite construir cadenas de transformación sin copiar datos entre pasos.
Una característica importante: CIImage no está vinculado a la resolución de pantalla ni al espacio de color hasta el momento del renderizado. El mismo CIImage se puede renderizar en un UIImage para pantalla y en un archivo TIFF para impresión con diferentes parámetros — CoreImage adapta automáticamente el procesamiento al contexto de destino.
CIFilter es la clase principal para aplicar efectos. Cada CIFilter es un programa shader con parámetros de entrada (inputImage, inputIntensity, inputRadius, etc.) y una imagen de salida. Apple proporciona más de 200 CIFilter integrados, agrupados por categorías: CICategoryColorEffect (corrección de color), CICategoryBlur (desenfoque), CICategoryStylize (estilización), CICategoryGeometryAdjust (transformaciones geométricas).
Para crear un CIFilter personalizado, el desarrollador escribe un shader Metal (CIKernel) — un shader de fragmentos en Metal Shading Language que procesa cada píxel de forma independiente. Después de la compilación, el shader se registra como una subclase de CIFilter y puede usarse en cadenas junto con los filtros integrados de Apple.
| Categoría | Ejemplo de filtro | Propósito |
|---|---|---|
| ColorEffect | CIColorControls | Brillo, contraste, saturación |
| Blur | CIGaussianBlur | Desenfoque gaussiano con radio ajustable |
| Stylize | CIPixellate | Pixelado con escala especificada |
| GeometryAdjust | CIAffineTransform | Rotación, escala, traslación mediante matriz afín |
| Composite | CISourceOverCompositing | Composición de imágenes con canal alfa |
CIContext es un objeto pesado que gestiona la asignación de recursos de GPU, compilación de shaders y almacenamiento en búfer. Crear un CIContext es una operación costosa, por lo que Apple recomienda crearlo una vez durante todo el ciclo de vida de la aplicación y reutilizarlo. El contexto está vinculado a una GPU específica (Metal, OpenGL) o CPU y determina el espacio de color de la imagen de salida.
La biblioteca CIFilter se expande constantemente: iOS 17 agregó nuevos filtros para procesamiento HDR y aprendizaje automático. Todos los filtros integrados están documentados en la Documentación para Desarrolladores de Apple y se pueden buscar por categorías o nombres. Para descubrir los filtros disponibles en el dispositivo, use CIFilter.filterNames(inCategory:).
La capacidad principal de CoreImage es componer múltiples CIFilter en una cadena. La salida de un filtro se alimenta a la entrada de otro a través del parámetro inputImage. CoreImage optimiza la cadena en la etapa de renderizado: los filtros adyacentes que trabajan en el mismo espacio de color se combinan en un solo pase de GPU (kernel fusion). Esto proporciona una ganancia de rendimiento sin intervención del desarrollador.
Para crear un efecto personalizado, el desarrollador escribe una función Metal con la anotación [[kernel]]. La función recibe coordenadas de píxel y devuelve un color. CoreImage pasa el shader a la GPU, donde se ejecuta en paralelo para todos los píxeles de la imagen. Los filtros personalizados son especialmente útiles para efectos visuales únicos: sepia con curva no lineal, desenfoque de dispersión o simulación de grano de película.
#include <CoreImage/CoreImage.h>
[[kernel]] float4 customFilter(sample_t s, float intensity) {
float4 result;
result.rgb = s.rgb * (1.0 - intensity) + s.r * intensity;
result.a = s.a;
return result;
}
CoreImage gestiona automáticamente la caché de resultados intermedios. Si la misma cadena de filtros se aplica a diferentes imágenes, CoreImage puede reutilizar los shaders compilados. Para máximo rendimiento, evite crear un CIContext para cada fotograma — use un solo contexto y reestablezca los parámetros de entrada del filtro.
CIDetector es un subsistema de CoreImage para detectar objetos semánticos en una imagen sin usar Vision o Core ML. CIDetector admite cuatro tipos de detección: rostros (CIDetectorTypeFace), texto (CIDetectorTypeText), códigos QR (CIDetectorTypeQRCode) y rectángulos (CIDetectorTypeRectangle). El detector funciona en la CPU con optimización para instrucciones NEON, lo que garantiza una velocidad estable en dispositivos sin GPU potente.
El detector de rostros CIDetectorTypeFace devuelve un array de CIFaceFeature con coordenadas de los límites del rostro, posición de ojos y boca. Desde iOS 12, CIDetector también detecta sonrisas (hasSmile) y la posición del ojo izquierdo/derecho (leftEyeClosed, rightEyeClosed). La precisión de detección es suficiente para la mayoría de aplicaciones AR y de fotos, pero para escenarios críticos Apple recomienda Vision.framework.
CIDetectorTypeRectangle encuentra áreas rectangulares en una imagen — documentos, tarjetas de visita, pantallas de dispositivos. El detector devuelve CIRectangleFeature con cuatro puntos que forman el contorno del rectángulo. Según WWDC 2024, el detector de rectángulos utiliza la misma arquitectura de red neuronal que Vision, pero con menor consumo de memoria. Esto lo hace preferible para el procesamiento de flujo de fotogramas en tiempo real, por ejemplo, en aplicaciones de escáner de documentos.
Ejemplos prácticos ayudarán a consolidar la comprensión de CoreImage. Veamos dos escenarios típicos: aplicar un filtro de color a una foto y detección de rostros con dibujo de rectángulo delimitador.
Un ejemplo básico del filtro CISepiaTone, que convierte una imagen en color a tonos sepia. El filtro acepta el parámetro inputIntensity de 0 (original) a 1 (efecto máximo). Observe la evaluación perezosa: el CIImage devuelto por filter.outputImage no contiene píxeles — el renderizado solo ocurre cuando se llama a context.createCGImage.
import CoreImage
guard let inputImage = CIImage(image: uiImage) else { return }
let filter = CIFilter(name: "CISepiaTone")
filter?.setValue(inputImage, forKey: kCIInputImageKey)
filter?.setValue(0.8, forKey: kCIInputIntensityKey)
let context = CIContext()
let outputImage = filter?.outputImage
let cgImage = context.createCGImage(outputImage!, from: inputImage.extent)
let resultImage = UIImage(cgImage: cgImage!)
El siguiente ejemplo usa CIDetector para buscar rostros en una imagen y dibujar un rectángulo alrededor de cada rostro detectado. CIFaceFeature contiene coordenadas en el sistema de coordenadas de la imagen (origen en la esquina inferior izquierda), por lo que al dibujar en UIKit se requiere una transformación de coordenadas mediante transformación afín.
let detector = CIDetector(
ofType: CIDetectorTypeFace,
context: context,
options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]
)
let features = detector?.features(in: inputImage) as? [CIFaceFeature]
for face in features ?? [] {
print("Face bounds: \(face.bounds)")
if face.hasSmile {
print("La persona sonríe")
}
}
El ejemplo final demuestra una cadena de tres filtros: corrección de color, viñeteado y superposición de textura. Observe que el outputImage del primer filtro se pasa como inputImage al segundo — sin renderizado intermedio. Cuando se llama a createCGImage, CoreImage combina las tres operaciones en un solo pase de GPU.
let colorFilter = CIFilter(name: "CIColorControls")
colorFilter?.setValue(inputImage, forKey: kCIInputImageKey)
colorFilter?.setValues([
kCIInputBrightnessKey: 0.1,
kCIInputContrastKey: 1.2
])
let vignetteFilter = CIFilter(name: "CIVignette")
vignetteFilter?.setValue(colorFilter?.outputImage, forKey: kCIInputImageKey)
vignetteFilter?.setValue(2.0, forKey: "inputRadius")
let finalImage = vignetteFilter?.outputImage
let result = context.createCGImage(finalImage!, from: inputImage.extent)
Preguntas frecuentes
CoreImage funciona en la GPU y está optimizado para operaciones de píxeles (filtros, corrección de color), mientras que Core Graphics es una biblioteca de CPU para dibujo vectorial y contextos 2D. CoreImage es más rápido para el procesamiento masivo de imágenes, Core Graphics es más preciso para el dibujo paso a paso de interfaces.
Sí — CoreImage admite el procesamiento de fotogramas de video individuales a través de AVPlayerItemVideoOutput o AVCaptureOutput. Para procesamiento en streaming, use AVVideoComposition con CIFilter, lo que permite aplicar efectos sin copiar fotogramas entre CPU y GPU.
CoreImage por defecto trabaja en el espacio de color sRGB (kCGColorSpaceSRGB). Al crear un CIContext, se puede especificar un espacio alternativo — sRGB lineal extendido para HDR o Display P3 para pantallas de amplia gama.
No hay límite en la cantidad de filtros en una cadena, pero cada 5–7 filtros consecutivos crean un pase adicional de GPU. Para más de 10 filtros, se recomienda dividir la cadena en grupos y renderizar resultados intermedios para evitar exceder el límite de registros del shader.
Sí — CIDetector funciona en la CPU usando instrucciones NEON en todos los dispositivos con iOS 5.0 y superior. La precisión de detección es la misma en todos los dispositivos, pero la velocidad es mayor en chips Apple A12+ debido a la aceleración hardware de redes neuronales.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también