Το CoreImage είναι ένα framework της Apple για επεξεργασία εικόνων και βίντεο σε πραγματικό χρόνο, παρέχοντας δεκάδες ενσωματωμένα CIFilter για διόρθωση χρωμάτων, θόλωση, επικάλυψη υφών και αναγνώριση. Σύμφωνα με το Apple Documentation, το CoreImage χρησιμοποιεί GPU για υψηλής απόδοσης επεξεργασία pixel σε συσκευές iOS. Το framework υποστηρίζει το CIImage ως αμετάβλητο αντικείμενο εικόνας και αλυσίδες φίλτρων για σύνθεση εφέ χωρίς απώλεια ποιότητας.
Βασικά σημεία
Το CoreImage είναι ένα framework της Apple για επεξεργασία bitmap εικόνων και βίντεο, που παρουσιάστηκε για πρώτη φορά στο macOS 10.4 Tiger και μεταφέρθηκε στο iOS 5.0. Σε αντίθεση με το Core Graphics ή το UIKit, το CoreImage λειτουργεί σε επίπεδο pixel shaders, χρησιμοποιώντας GPU για παράλληλους υπολογισμούς. Αυτό επιτρέπει την εφαρμογή σύνθετων εφέ — θόλωση, διόρθωση χρωμάτων, μόρφωση — σε εικόνες megapixel ανάλυσης σε χιλιοστά του δευτερολέπτου.
Η αρχιτεκτονική του CoreImage βασίζεται στην έννοια της τεμπέλικης αξιολόγησης (lazy evaluation): το CIFilter δεν εκτελεί επεξεργασία μέχρι τη στιγμή της απόδοσης στο CIContext. Ο προγραμματιστής δημιουργεί μια αλυσίδα από πολλά CIFilter, συνδέοντας την έξοδο ενός φίλτρου με την είσοδο ενός άλλου, και μόνο η κλήση render ενεργοποιεί τον πλήρη αγωγό GPU. Αυτό ελαχιστοποιεί τον αριθμό των περασμάτων μέσω της κάρτας γραφικών και διατηρεί την απόδοση.
Το CoreImage υποστηρίζει ευρεία χρωματική γκάμα (P3, sRGB, γραμμικό sRGB), εικόνες HDR και εργασία με μορφές pixel 16-bit και 32-bit. Σε συσκευές με Neural Engine, το CoreImage μπορεί να συνδυάσει GPU shaders με Core ML για έξυπνη επεξεργασία — για παράδειγμα, αυτόματη διόρθωση χρωμάτων βάσει μηχανικής μάθησης, όπως υλοποιείται στην εφαρμογή Photos στο iOS 17.
Τρεις βασικές κλάσεις αποτελούν τον πυρήνα του CoreImage: CIImage (δεδομένα), CIFilter (λειτουργία) και CIContext (περιβάλλον εκτέλεσης). Κάθε κλάση είναι υπεύθυνη για τη δική της φάση στον αγωγό και δεν αναμιγνύει αρμοδιότητες.
CIImage είναι ένα ελαφρύ αντικείμενο που περιγράφει την εικόνα, αλλά δεν περιέχει άμεσα δεδομένα pixel. Μπορεί να δημιουργηθεί από UIImage, CGImage, υφή Metal, υφή GL ή αρχείο στο δίσκο. Το CIImage είναι αμετάβλητο — οποιαδήποτε εφαρμογή φίλτρου δημιουργεί ένα νέο CIImage χωρίς να τροποποιεί το αρχικό. Αυτό επιτρέπει τη δημιουργία αλυσίδων μετασχηματισμών χωρίς αντιγραφή δεδομένων μεταξύ των βημάτων.
Σημαντικό χαρακτηριστικό: το CIImage δεν είναι δεσμευμένο σε ανάλυση οθόνης ή χρωματικό χώρο μέχρι τη στιγμή της απόδοσης. Το ίδιο CIImage μπορεί να αποδοθεί ως UIImage για την οθόνη και ως αρχείο TIFF για εκτύπωση με διαφορετικές παραμέτρους — το CoreImage προσαρμόζει αυτόματα την επεξεργασία στο περιβάλλον προορισμού.
CIFilter είναι η κύρια κλάση για εφαρμογή εφέ. Κάθε CIFilter αντιπροσωπεύει ένα πρόγραμμα shader με παραμέτρους εισόδου (inputImage, inputIntensity, inputRadius κ.λπ.) και μία εικόνα εξόδου. Η Apple παρέχει πάνω από 200 ενσωματωμένα CIFilter, ομαδοποιημένα σε κατηγορίες: CICategoryColorEffect (διόρθωση χρωμάτων), CICategoryBlur (θόλωση), CICategoryStylize (στυλιζάρισμα), CICategoryGeometryAdjust (γεωμετρικοί μετασχηματισμοί).
Για τη δημιουργία ενός προσαρμοσμένου CIFilter, ο προγραμματιστής γράφει ένα Metal shader (CIKernel) — ένα fragment shader στη γλώσσα Metal Shading Language, που επεξεργάζεται κάθε pixel ανεξάρτητα. Μετά τη μεταγλώττιση, το shader καταχωρείται ως υποκλάση του CIFilter και μπορεί να χρησιμοποιηθεί σε αλυσίδες μαζί με τα ενσωματωμένα φίλτρα της Apple.
| Κατηγορία | Παράδειγμα φίλτρου | Σκοπός |
|---|---|---|
| ColorEffect | CIColorControls | Φωτεινότητα, αντίθεση, κορεσμός |
| Blur | CIGaussianBlur | Θόλωση Gauss με ρυθμιζόμενη ακτίνα |
| Stylize | CIPixellate | Pixel απεικόνιση με καθορισμένη κλίμακα |
| GeometryAdjust | CIAffineTransform | Περιστροφή, κλίμακα, μετατόπιση μέσω affine μήτρας |
| Composite | CISourceOverCompositing | Επικάλυψη εικόνων με κανάλι άλφα |
CIContext είναι ένα βαρύ αντικείμενο που διαχειρίζεται την κατανομή πόρων GPU, τη μεταγλώττιση shaders και την προσωρινή αποθήκευση. Η δημιουργία CIContext είναι ακριβή λειτουργία, γι' αυτό η Apple συνιστά τη δημιουργία του μία φορά για όλο τον κύκλο ζωής της εφαρμογής και την επαναχρησιμοποίησή του. Το περιβάλλον συνδέεται με συγκεκριμένη GPU (Metal, OpenGL) ή CPU και καθορίζει τον χρωματικό χώρο της εικόνας εξόδου.
Η βιβλιοθήκη CIFilter επεκτείνεται συνεχώς: το iOS 17 πρόσθεσε νέα φίλτρα για επεξεργασία HDR και μηχανική μάθηση. Όλα τα ενσωματωμένα φίλτρα είναι τεκμηριωμένα στο Apple Developer Documentation και μπορούν να αναζητηθούν ανά κατηγορία ή όνομα. Για εντοπισμό διαθέσιμων φίλτρων στη συσκευή, χρησιμοποιήστε το CIFilter.filterNames(inCategory:).
Η κύρια δυνατότητα του CoreImage είναι η σύνθεση πολλαπλών CIFilter σε αλυσίδα. Η έξοδος ενός φίλτρου τροφοδοτείται ως είσοδος στο επόμενο μέσω της παραμέτρου inputImage. Το CoreImage βελτιστοποιεί την αλυσίδα στο στάδιο της απόδοσης: γειτονικά φίλτρα που λειτουργούν στον ίδιο χρωματικό χώρο συγχωνεύονται σε ένα πέρασμα GPU (kernel fusion). Αυτό δίνει κέρδος στην απόδοση χωρίς παρέμβαση του προγραμματιστή.
Για τη δημιουργία δικού σας εφέ, ο προγραμματιστής γράφει μια συνάρτηση Metal με σχολιασμό [[kernel]]. Η συνάρτηση δέχεται συντεταγμένες pixel και επιστρέφει χρώμα. Το CoreImage στέλνει το shader στη GPU, όπου εκτελείται παράλληλα για όλα τα pixel της εικόνας. Τα προσαρμοσμένα φίλτρα είναι ιδιαίτερα χρήσιμα για μοναδικά οπτικά εφέ: sepia με μη γραμμική καμπύλη, θόλωση διασποράς ή προσομοίωση κόκκων φιλμ.
#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 διαχειρίζεται αυτόματα την προσωρινή αποθήκευση ενδιάμεσων αποτελεσμάτων. Αν η ίδια αλυσίδα φίλτρων εφαρμόζεται σε διαφορετικές εικόνες, το CoreImage μπορεί να επαναχρησιμοποιήσει μεταγλωττισμένους shaders. Για μέγιστη απόδοση, αποφύγετε τη δημιουργία CIContext για κάθε καρέ — χρησιμοποιήστε ένα περιβάλλον και επαναρυθμίστε τις παραμέτρους εισόδου του φίλτρου.
CIDetector είναι το υποσύστημα του CoreImage για ανίχνευση σημασιολογικών αντικειμένων στην εικόνα χωρίς τη χρήση Vision ή Core ML. Το CIDetector υποστηρίζει τέσσερις τύπους ανίχνευσης: προσώπων (CIDetectorTypeFace), κειμένου (CIDetectorTypeText), QR κωδικών (CIDetectorTypeQRCode) και ορθογωνίων (CIDetectorTypeRectangle). Ο ανιχνευτής λειτουργεί σε CPU με βελτιστοποίηση NEON, εξασφαλίζοντας σταθερή ταχύτητα σε συσκευές χωρίς ισχυρή GPU.
Ο ανιχνευτής προσώπων CIDetectorTypeFace επιστρέφει έναν πίνακα CIFaceFeature με συντεταγμένες ορίων προσώπου, θέση ματιών και στόματος. Από το iOS 12, το CIDetector ανιχνεύει επίσης το χαμόγελο (hasSmile) και τη θέση αριστερού/δεξιού ματιού (leftEyeClosed, rightEyeClosed). Η ακρίβεια ανίχνευσης είναι επαρκής για τις περισσότερες εφαρμογές AR και φωτογραφίας, αλλά για κρίσιμα σενάρια η Apple συνιστά το Vision.framework.
CIDetectorTypeRectangle εντοπίζει ορθογώνιες περιοχές στην εικόνα — έγγραφα, επαγγελματικές κάρτες, οθόνες συσκευών. Ο ανιχνευτής επιστρέφει CIRectangleFeature με τέσσερα σημεία που σχηματίζουν το περίγραμμα του ορθογωνίου. Σύμφωνα με το WWDC 2024, ο ανιχνευτής ορθογωνίων χρησιμοποιεί την ίδια αρχιτεκτονική νευρωνικού δικτύου με το Vision, αλλά με μικρότερη κατανάλωση μνήμης. Αυτό τον καθιστά προτιμότερο για επεξεργασία ροής καρέ σε πραγματικό χρόνο, για παράδειγμα, σε εφαρμογές σαρωτή εγγράφων.
Πρακτικά παραδείγματα θα βοηθήσουν να εμπεδώσετε την κατανόηση του CoreImage. Ας εξετάσουμε δύο τυπικά σενάρια: εφαρμογή χρωματικού φίλτρου σε φωτογραφία και ανίχνευση προσώπων με σχεδίαση πλαισίου.
Βασικό παράδειγμα του CISepiaTone φίλτρου, το οποίο μετατρέπει μια έγχρωμη εικόνα σε τόνους sepia. Το φίλτρο δέχεται την παράμετρο inputIntensity από 0 (αρχική) έως 1 (μέγιστο εφέ). Σημειώστε την τεμπέλικη αξιολόγηση: το CIImage που επιστρέφεται από το filter.outputImage δεν περιέχει pixel — η απόδοση γίνεται μόνο κατά την κλήση 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!)
Το επόμενο παράδειγμα χρησιμοποιεί το CIDetector για την εύρεση προσώπων σε μια εικόνα και τη σχεδίαση ορθογωνίου γύρω από κάθε πρόσωπο που εντοπίζεται. Το CIFaceFeature περιέχει συντεταγμένες στο σύστημα συντεταγμένων της εικόνας (αρχή στην κάτω αριστερή γωνία), επομένως κατά τη σχεδίαση σε UIKit απαιτείται μετατροπή συντεταγμένων μέσω 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("Το άτομο χαμογελά")
}
}
Το τελικό παράδειγμα παρουσιάζει αλυσίδα τριών φίλτρων: διόρθωση χρωμάτων, βινιετάρισμα και επικάλυψη υφής. Σημειώστε ότι το outputImage του πρώτου φίλτρου μεταφέρεται ως inputImage στο δεύτερο — χωρίς ενδιάμεση απόδοση. Κατά την κλήση createCGImage, το CoreImage συνδυάζει και τις τρεις λειτουργίες σε ένα πέρασμα 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)
Συχνές ερωτήσεις
Το CoreImage λειτουργεί στη GPU και είναι βελτιστοποιημένο για λειτουργίες pixel (φίλτρα, διόρθωση χρωμάτων), ενώ το Core Graphics είναι βιβλιοθήκη CPU για διανυσματική σχεδίαση και 2D περιβάλλοντα. Το CoreImage είναι ταχύτερο για μαζική επεξεργασία εικόνων, το Core Graphics είναι ακριβέστερο για σταδιακή σχεδίαση διεπαφής.
Ναι — το CoreImage υποστηρίζει επεξεργασία μεμονωμένων καρέ βίντεο μέσω AVPlayerItemVideoOutput ή AVCaptureOutput. Για επεξεργασία ροής, χρησιμοποιήστε το AVVideoComposition with CIFilter, που επιτρέπει την εφαρμογή εφέ χωρίς αντιγραφή καρέ μεταξύ CPU και GPU.
Το CoreImage από προεπιλογή λειτουργεί στον χρωματικό χώρο εργασίας sRGB (kCGColorSpaceSRGB). Κατά τη δημιουργία CIContext, μπορείτε να καθορίσετε εναλλακτικό χώρο — extended linear sRGB για HDR ή Display P3 για οθόνες με ευρεία γκάμα.
Δεν υπάρχει περιορισμός στον αριθμό φίλτρων σε μια αλυσίδα, αλλά κάθε 5–7 διαδοχικά φίλτρα δημιουργούν ένα επιπλέον πέρασμα GPU. Για περισσότερα από 10 φίλτρα, συνιστάται να χωρίσετε την αλυσίδα σε ομάδες και να αποδίδετε ενδιάμεσα αποτελέσματα, ώστε να αποφευχθεί η υπέρβαση του ορίου καταχωρητών shader.
Ναι — το CIDetector λειτουργεί σε CPU χρησιμοποιώντας NEON εντολές σε όλες τις συσκευές με iOS 5.0 και νεότερο. Η ακρίβεια ανίχνευσης είναι ίδια σε όλες τις συσκευές, αλλά η ταχύτητα είναι μεγαλύτερη σε τσιπ Apple A12+ λόγω υλικής επιτάχυνσης νευρωνικών δικτύων.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης