CoreImage este un framework Apple pentru procesarea imaginilor și video în timp real, care oferă zeci de CIFilter încorporate pentru corecția culorilor, estompare, suprapunere de texturi și detectare. Potrivit Apple Documentation, CoreImage utilizează GPU-ul pentru procesarea de înaltă performanță a pixelilor pe dispozitivele iOS. Framework-ul acceptă CIImage ca obiect de imagine imutabil și lanțuri de filtre pentru compunerea efectelor fără pierdere de calitate.
Principalele puncte
CoreImage este un framework Apple pentru procesarea imaginilor raster și video, introdus prima dată în macOS 10.4 Tiger și portat pe iOS 5.0. Spre deosebire de Core Graphics sau UIKit, CoreImage funcționează la nivelul shader-elor de pixeli, utilizând GPU-ul pentru calcule paralele. Acest lucru permite aplicarea de efecte complexe — estompare, corecție a culorilor, morfing — imaginilor de rezoluție megapixel în milisecunde.
Arhitectura CoreImage este construită pe conceptul de evaluare leneșă (lazy evaluation): CIFilter nu execută procesarea până la momentul randării în CIContext. Dezvoltatorul construiește un lanț din mai multe CIFilter, conectând ieșirea unui filtru la intrarea altuia, iar doar apelul render lansează conducta completă GPU. Acest lucru minimizează numărul de treceri prin placa grafică și menține performanța.
CoreImage acceptă gamă largă de culori (P3, sRGB, sRGB liniar), imagini HDR și lucrul cu formate de pixeli pe 16 biți și 32 de biți. Pe dispozitivele cu Neural Engine, CoreImage poate combina shader-ele GPU cu Core ML pentru procesare inteligentă — de exemplu, corecția automată a culorilor bazată pe învățare automată, așa cum este implementată în aplicația Foto pe iOS 17.
Trei clase principale formează nucleul CoreImage: CIImage (date), CIFilter (operație) și CIContext (mediu de execuție). Fiecare clasă răspunde de faza sa din conductă și nu amestecă responsabilitățile.
CIImage este un obiect ușor care descrie imaginea, dar nu conține direct date de pixeli. Poate fi creat din UIImage, CGImage, textură Metal, textură GL sau fișier pe disc. CIImage este imutabil — orice aplicare a unui filtru creează un nou CIImage fără a modifica originalul. Acest lucru permite construirea de lanțuri de transformări fără copierea datelor între pași.
Caracteristică importantă: CIImage nu este legat de rezoluția ecranului sau de spațiul de culoare până la momentul randării. Același CIImage poate fi randat în UIImage pentru ecran și în fișier TIFF pentru tipărire cu parametri diferiți — CoreImage adaptează automat procesarea la contextul țintă.
CIFilter este clasa principală pentru aplicarea efectelor. Fiecare CIFilter reprezintă un program shader cu parametri de intrare (inputImage, inputIntensity, inputRadius etc.) și o imagine de ieșire. Apple livrează peste 200 de CIFilter încorporate, grupate pe categorii: CICategoryColorEffect (corecția culorilor), CICategoryBlur (estompare), CICategoryStylize (stilizare), CICategoryGeometryAdjust (transformări geometrice).
Pentru a crea un CIFilter personalizat, dezvoltatorul scrie un shader Metal (CIKernel) — un shader de fragment în limbajul Metal Shading Language care procesează fiecare pixel independent. După compilare, shader-ul este înregistrat ca subclasă a CIFilter și poate fi utilizat în lanțuri la fel ca filtrele încorporate Apple.
| Categorie | Exemplu filtru | Destinație |
|---|---|---|
| ColorEffect | CIColorControls | Luminozitate, contrast, saturație |
| Blur | CIGaussianBlur | Estompare Gaussiană cu rază reglabilă |
| Stylize | CIPixellate | Pixelizarea imaginii cu scară specificată |
| GeometryAdjust | CIAffineTransform | Rotire, scalare, deplasare prin matrice affine |
| Composite | CISourceOverCompositing | Suprapunerea imaginilor cu canal alfa |
CIContext este un obiect greu care gestionează alocarea resurselor GPU, compilarea shader-elor și bufferizarea. Crearea unui CIContext este o operație costisitoare, de aceea Apple recomandă să-l creați o singură dată pentru întreaga durată de viață a aplicației și să-l reutilizați. Contextul este legat de un GPU specific (Metal, OpenGL) sau CPU și determină spațiul de culoare al imaginii de ieșire.
Biblioteca CIFilter se extinde constant: iOS 17 a adăugat filtre noi pentru procesarea HDR și învățarea automată. Toate filtrele încorporate sunt documentate în Apple Developer Documentation, pot fi căutate după categorii sau nume. Pentru detectarea filtrelor disponibile pe dispozitiv, utilizați CIFilter.filterNames(inCategory:).
Capacitatea principală a CoreImage — compunerea mai multor CIFilter într-un lanț. Ieșirea unui filtru este furnizată la intrarea următorului prin parametrul inputImage. CoreImage optimizează lanțul în faza de randare: filtrele adiacente care lucrează în același spațiu de culoare sunt combinate într-o singură trecere GPU (kernel fusion). Aceasta oferă un câștig de performanță fără intervenția dezvoltatorului.
Pentru a crea un efect propriu, dezvoltatorul scrie o funcție Metal cu adnotarea [[kernel]]. Funcția primește coordonatele pixelului și returnează culoarea. CoreImage trimite shader-ul pe GPU, unde este executat paralel pentru toți pixelii imaginii. Filtrele personalizate sunt deosebit de utile pentru efecte vizuale unice: sepia cu curbă neliniară, estompare prin dispersie sau imitarea granulației de film.
#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 gestionează automat memoria cache a rezultatelor intermediare. Dacă același lanț de filtre este aplicat la imagini diferite, CoreImage poate reutiliza shader-ele compilate. Pentru performanță maximă, evitați crearea unui CIContext pentru fiecare cadru — utilizați un singur context și resetați parametrii de intrare ai filtrului.
CIDetector este subsistemul CoreImage pentru detectarea obiectelor semantice în imagine fără utilizarea Vision sau Core ML. CIDetector acceptă patru tipuri de detecție: fețe (CIDetectorTypeFace), text (CIDetectorTypeText), coduri QR (CIDetectorTypeQRCode) și dreptunghiuri (CIDetectorTypeRectangle). Detectorul funcționează pe CPU cu optimizare pentru instrucțiunile NEON, ceea ce asigură o viteză stabilă pe dispozitivele fără un GPU puternic.
Detectorul de fețe CIDetectorTypeFace returnează un array de CIFaceFeature cu coordonatele limitelor feței, poziția ochilor și a gurii. începând cu iOS 12, CIDetector determină, de asemenea, zâmbetul (hasSmile) și poziția ochiului stâng/drept (leftEyeClosed, rightEyeClosed). Precizia detecției este suficientă pentru majoritatea aplicațiilor AR și foto, dar pentru scenarii critice Apple recomandă Vision.framework.
CIDetectorTypeRectangle găsește zone dreptunghiulare în imagine — documente, cărți de vizită, ecrane de dispozitive. Detectorul returnează CIRectangleFeature cu patru puncte care formează conturul dreptunghiului. Potrivit WWDC 2024, detectorul de dreptunghiuri utilizează aceeași arhitectură de rețea neurală ca Vision, dar cu un consum mai mic de memorie. Aceasta îl face preferabil pentru procesarea fluxului de cadre în timp real, de exemplu în aplicațiile de scanare a documentelor.
Exemplele practice vor ajuta la consolidarea înțelegerii CoreImage. Să analizăm două scenarii tipice: aplicarea unui filtru de culoare unei fotografii și detectarea fețelor cu desenarea unui cadru.
Exemplul de bază al filtrului CISepiaTone, care transformă imaginea color în tonuri de sepia. Filtrul acceptă parametrul inputIntensity de la 0 (original) la 1 (efect maxim). Observați evaluarea leneșă: CIImage returnat de filter.outputImage nu conține pixeli — randarea are loc doar la apelarea 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!)
Următorul exemplu utilizează CIDetector pentru a găsi fețe în imagine și a desena un dreptunghi în jurul fiecărei fețe găsite. CIFaceFeature conține coordonate în sistemul imaginii (originea în colțul din stânga jos), prin urmare la desenarea pe UIKit este necesară transformarea coordonatelor prin affine transform.
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("Persoana zâmbește")
}
}
Exemplul final demonstrează un lanț de trei filtre: corecția culorilor, vignetare și suprapunere de textură. Observați că outputImage al primului filtru este transmis ca inputImage celui de-al doilea — fără randare intermediară. La apelarea createCGImage, CoreImage combină toate cele trei operații într-o singură trecere 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)
Întrebări frecvente
CoreImage funcționează pe GPU și este optimizat pentru operații pe pixeli (filtre, corecția culorilor), în timp ce Core Graphics este o bibliotecă CPU pentru desenare vectorială și contextele 2D. CoreImage este mai rapid pentru procesarea în masă a imaginilor, Core Graphics mai precis pentru desenarea pas cu pas a interfeței.
Da — CoreImage acceptă procesarea cadrelor video individuale prin AVPlayerItemVideoOutput sau AVCaptureOutput. Pentru procesare în flux, utilizați AVVideoComposition with CIFilter, ceea ce permite aplicarea efectelor fără copierea cadrelor între CPU și GPU.
CoreImage funcționează implicit în spațiul de culoare de lucru sRGB (kCGColorSpaceSRGB). La crearea CIContext se poate specifica un spațiu alternativ — extended linear sRGB pentru HDR sau Display P3 pentru afișaje cu gamă largă.
Nu există o limitare a numărului de filtre în lanț, dar fiecare 5–7 filtre consecutive creează o trecere GPU suplimentară. Pentru mai mult de 10 filtre, se recomandă împărțirea lanțului în grupuri și randarea rezultatelor intermediare pentru a evita depășirea limitei registrelor shader-ului.
Da — CIDetector funcționează pe CPU utilizând instrucțiunile NEON pe toate dispozitivele cu iOS 5.0 și mai recent. Precizia detecției este aceeași pe toate dispozitivele, dar viteza este mai mare pe cipurile Apple A12+ datorită accelerării hardware a rețelelor neuronale.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și