Core Graphics هو إطار العرض ثنائي الأبعاد من Apple، وهو جزء من Core Foundation، ومتاح على iOS وmacOS وtvOS وwatchOS. يوفر واجهة برمجة تطبيقات C منخفضة المستوى للعمل مع الرسومات المتجهة والنقطية، بما في ذلك رسم المسارات والتدرجات والظلال والصور والنصوص. يعمل Core Graphics كأساس لـ UIKit وSwiftUI وAppKit. وفقًا لـ Apple Developer Documentation، 2026، يُستخدم الإطار في أكثر من 90% من تطبيقات iOS، لأن كل عنصر مرئي يمر عبر Core Graphics أو نظيره العتادي.
الرئيسية
Core Graphics (المعروف أيضًا باسم Quartz 2D) هو إطار يطبق محرك الرسومات ثنائية الأبعاد من Apple. يعتمد على مكتبة Quartz المحمولة للرسومات ويستخدم نموذج رسم قائم على الصفحة، حيث كل إجراء هو أمر في تسلسل يشبه الرسم على الورق. يدعم Core Graphics منع التعرجات والشفافية (تكوين ألفا) وفضاءات ألوان ICC.
هندسة Core Graphics مبنية حول سياق الرسم (CGContext) الذي يغلف جهاز الإخراج الهدف — الشاشة والطابعة ومستند PDF أو المخزن المؤقت النقطي. يدير السياق الإعدادات الحالية: اللون وسمك الخط والتحويل ومنطقة القص والخطوط. يوفر هذا النهج واجهة برمجة تطبيقات موحدة لأجهزة الإخراج المختلفة دون تغيير كود الرسم.
يعمل Core Graphics بشكل أساسي على وحدة المعالجة المركزية، باستخدام نموذج متجه (مستقل عن الدقة). وهذا يعني أن الخطوط والمنحنيات تتم نقطتها بدقة الجهاز الحالية عند الرسم. على عكس Metal، لا يتطلب Core Graphics إدارة صريحة لموارد GPU — حيث يتولى النظام جميع عمليات التحسين. بالنسبة لمعظم المهام ثنائية الأبعاد (الرسومات والرسوم البيانية وعناصر واجهة المستخدم المخصصة)، فإن أداء Core Graphics كافٍ للحفاظ على 60 إطارًا في الثانية.
Core Graphics يتضمن حوالي 50 نوعًا أساسيًا (أنواع معتمة)، كل منها مسؤول عن وظيفة محددة. تتبع جميع الأنواع قواعد إدارة الذاكرة في Core Foundation: يتم إنشاؤها من خلال دوال تحتوي على Create في الاسم، وتتطلب استدعاء CGRelease، وهي غير متوافقة مع ARC في Objective-C (ومع ذلك يدير Swift الذاكرة تلقائيًا من خلال تعليقات CF_RETURNS_RETAINED).
CGContext — سياق الرسم، النوع المركزي للإطار. CGPath — مسار متجه غير قابل للتغيير. CGColor — لون مع فضاء لوني محدد. CGGradient — تعبئة تدرجية. CGImage — صورة نقطية. CGLayer — مخزن مؤقت غير متصل محسّن للرسم المتكرر. CGDataProvider — مصدر بيانات للصور. CGColorSpace — فضاء لوني (sRGB، Display P3، Gray).
تم تصميم كل نوع لأقل عبء: يمكن تخزين CGPath مؤقتًا وإعادة استخدامه بين سياقات مختلفة، يتم تحويل CGColor إلى تمثيل عتادي GPU عند تمريره، يخزن CGLayer محتوى منقّط مسبقًا. هذه الهندسة تسمح لـ Core Graphics بالعمل بكفاءة في كل من مهام واجهة المستخدم البسيطة ومحررات الرسومات الاحترافية.
| النوع | الغرض | إدارة الذاكرة |
|---|---|---|
| CGContext | سياق الرسم | CFRelease أو تلقائي في Swift |
| CGPath | مسار متجه | CFRelease (غير قابل للتغيير) |
| CGColor | لون في فضاء لوني | CFRelease أو CGColorCreate |
| CGImage | صورة نقطية | CFRelease (بعد الإنشاء) |
| CGLayer | مخزن مؤقت غير متصل | CFRelease أو CGLayerCreate |
CGPath هو كائن غير قابل للتغيير يصف تسلسلًا من المقاطع الهندسية: خطوط مستقيمة ومنحنيات بيزير وأقواس وإغلاقات. على عكس UIBezierPath، لا يحتوي CGPath على طرق رسم — فهو يخزن الهندسة فقط. للرسم، يتم إضافة CGPath إلى السياق (CGContextAddPath) ثم يتم عرضه عبر strokePath أو fillPath. يضمن عدم التغيير أمان الخيوط وقابلية التخزين المؤقت.
CGPathCreateMutable ينشئ مسارًا قابلًا للتغيير (CGMutablePathRef) للبناء خطوة بخطوة. بعد التجميع النهائي، يتم تحويله إلى CGPathRef غير قابل للتغيير. توصي Apple بتقليل عدد النقاط في CGPath — فالمسارات المعقدة جدًا (أكثر من 1000 مقطع) تبطئ التنقيط. للتحسين، استخدم CGPathCreateCopyBySimplifyingPath الذي يزيل النقاط المتداخلة الزائدة.
لتحريك الشكل بين كائني CGPath، يمكنك استخدام CABasicAnimation على خاصية path لـ CAShapeLayer. القيد: يجب أن يكون لكل من CGPath نفس عدد المقاطع (نقاط التحكم). تتيح دالة CGPathApply اجتياز جميع عناصر المسار ومقارنة هيكلها. إذا لم تتطابق المقاطع، سيكون الرسم المتحرك متقطعًا — في هذه الحالة، استخدم CADisplayLink للاستيفاء اليدوي للنقاط.
// إنشاء مسار قابل للتغيير
let mutablePath = CGMutablePath()
mutablePath.moveTo(to: CGPoint(x: 0, y: 0))
mutablePath.addLine(to: CGPoint(x: 100, y: 0))
mutablePath.addLine(to: CGPoint(x: 100, y: 100))
mutablePath.closeSubpath()
// تحويل إلى غير قابل للتغيير للتخزين المؤقت الآمن
let immutablePath: CGPath = mutablePath
CATransaction.perform {
shapeLayer.path = immutablePath
}
CGGradient هو كائن يحدد انتقالًا سلسًا بين لونين أو أكثر على طول خط مستقيم (تدرج خطي) أو من المركز إلى الحواف (تدرج شعاعي). يتم إنشاء CGGradient مع فضاء لوني محدد ومصفوفة من CGColorRef ومصفوفة من مواضع التوقف من 0.0 إلى 1.0. بعد الإنشاء، يمكن إعادة استخدام التدرج عدة مرات في سياقات مختلفة.
CGShading هو آلية أكثر قوة تسمح بتعريف دالة تغيير اللون على طول المسار. على عكس CGGradient الذي يعمل مع مجموعة ثابتة من الألوان، يستخدم CGShading دالة رد اتصال (CGFunctionRef) تحسب اللون في كل نقطة. وهذا يتيح إنشاء تدرجات معقدة مع انتقالات غير خطية وأنظمة ألوان مركبة.
لرسم تدرج داخل شكل، يلزم وجود قص على مسار الشكل. الترتيب: إضافة المسار إلى السياق، استدعاء CGContextClip، ثم رسم التدرج. بدون قص، يملأ التدرج السياق بأكمله. في iOS، يُوصى باستخدام CGGradient كخيار أبسط وأكثر أداءً — CGShading مبرر فقط لدوال الألوان المخصصة.
func drawGradient(ctx: CGContext, rect: CGRect) {
let colors = [UIColor.red.cgColor, UIColor.blue.cgColor] as CFArray
guard let gradient = CGGradient(
colorsSpace: CGColorSpaceCreateDeviceRGB(),
colors: colors,
locations: [0.0, 1.0]
) else { return }
ctx.saveGState()
ctx.addEllipse(in: rect)
ctx.clip()
ctx.drawLinearGradient(
gradient,
start: CGPoint(x: rect.midX, y: rect.minY),
end: CGPoint(x: rect.midX, y: rect.maxY),
options: []
)
ctx.restoreGState()
}
CGImage هي صورة نقطية في Core Graphics يمكن تحميلها من ملف أو إنشاؤها برمجيًا أو الحصول عليها من UIImage. تحتوي CGImage على بيانات البكسل ومعلومات فضاء الألوان والحجم وعمق البت وتخطيط البيانات. على عكس UIImage، لا تدير CGImage تحجيم Retina — هذه المسؤولية تقع على المطور عبر معامل scale.
CGLayer هو مخزن مؤقت غير متصل للتنقيط المسبق للمحتوى الثابت. إذا تم تنفيذ نفس مجموعة أوامر الرسم بشكل متكرر (على سبيل المثال، نمط خلفية)، يقوم CGLayer بتنقيطها مرة واحدة ثم بنسخها ببساطة إلى السياق. وفقًا لـ Apple، يمكن أن يؤدي استخدام CGLayer إلى تسريع الرسم المتكرر بمقدار 2–5 مرات على CPU وما يصل إلى 10 مرات مع التسريع العتادي.
لتحميل الصور، استخدم CGImageSource — واجهة برمجة تطبيقات قوية لقراءة البيانات الوصفية والصور المصغرة والإطارات الفردية من GIF/APNG. تسمح CGImageSource بالتحميل التدريجي واسترجاع الأجزاء الضرورية فقط. عند العمل مع صور كبيرة (تتجاوز حجم الشاشة)، يُوصى بإنشاء CGImageSource مع التخزين المؤقت على القرص واستخدام CGImageSourceCreateThumbnailAtIndex لعرض نسخة مصغرة.
func createLayer(ctx: CGContext, size: CGSize) -> CGLayer? {
guard let layer = CGLayer(ctx, size: size, auxiliaryInfo: nil) else { return nil }
let layerCtx = layer.context !
// رسم مرة واحدة
layerCtx.setFillColor(UIColor.lightGray.cgColor)
layerCtx.addEllipse(in: CGRect(origin: .zero, size: size))
layerCtx.fillPath()
return layer
}
// الاستخدام في draw()
for i in 0..<20 {
ctx.draw(layer, at: CGPoint(x: CGFloat(i) * 30, y: 0))
}
لنبني عرضًا مخصصًا لعرض علامة مائية على صورة باستخدام Core Graphics. العلامة المائية تشمل نصًا شبه شفاف وشعارًا متجهًا متراكبين فوق الصورة الأصلية. يوضح الكود العمل مع CGContext وCGImage والنص والشفافية في سياق واحد.
class WatermarkView: UIView {
private let watermarkText = "IT Sectr"
private let watermarkOpacity: CGFloat = 0.3
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
// رسم صورة الخلفية
UIImage(named: "background")?.draw(in: rect)
// تكوين شفافية العلامة المائية
ctx.saveGState()
ctx.translateBy(x: rect.midX, y: rect.midY)
ctx.rotate(by: -.pi / 6)
// نص شبه شفاف
let attributes: NSAttributedString.Attributes = [
.font: UIFont.boldSystemFont(ofSize: 48),
.foregroundColor: UIColor.white.withAlphaComponent(watermarkOpacity)
]
let textSize = watermarkText.size(withAttributes: attributes)
watermarkText.draw(
at: CGPoint(x: -textSize.width / 2, y: -textSize.height / 2),
withAttributes: attributes
)
// أيقونة متجهة (دائرة مع صليب) أسفل النص
ctx.setStrokeColor(UIColor.white.withAlphaComponent(watermarkOpacity).cgColor)
ctx.setLineWidth(3)
ctx.addEllipse(in: CGRect(x: -25, y: -75, width: 50, height: 50))
ctx.strokePath()
ctx.moveTo(x: -15, y: -50)
ctx.addLineTo(x: 15, y: -50)
ctx.moveTo(x: 0, y: -65)
ctx.addLineTo(x: 0, y: -35)
ctx.strokePath()
ctx.restoreGState()
}
}
يستخدم الكود ميزات Core Graphics الرئيسية: saveGState/restoreGState لعزل تأثيرات العلامة المائية عن الخلفية، translateBy وrotate لتحديد المواقع والتدوير، نص شبه شفاف عبر withAlphaComponent وأيقونة متجهة عبر addEllipse وaddLineTo. العلامة المائية بأكملها تُرسم كتكوين واحد بعد صورة الخلفية.
عند إنشاء علامات مائية للصور في الإنتاج، من المهم مراعاة الأداء. إذا كانت الصورة أكبر من الشاشة، قم بتصغيرها باستخدام CGImageSourceCreateThumbnailAtIndex قبل تطبيق العلامة المائية. Core Graphics يعالج جميع العمليات على CPU — للمعالجة المجمعة لعشرات الصور، استخدم قائمة انتظار خلفية وCGBitmapContext لتجنب حظر واجهة المستخدم.
الأسئلة الشائعة
UIKit هو إطار واجهة مستخدم عالي المستوى يستخدم Core Graphics داخليًا للرسم. Core Graphics هي واجهة برمجة تطبيقات C منخفضة المستوى للرسومات ثنائية الأبعاد. UIKit أكثر ملاءمة للعناصر القياسية، بينما يمنح Core Graphics تحكمًا كاملاً في كل بكسل.
Core Graphics مناسب للرسومات ثنائية الأبعاد الثابتة والرسوم البيانية وعناصر واجهة المستخدم المخصصة. Metal للرسومات ثلاثية الأبعاد والرسوم المتحركة المعقدة ومعالجة مصفوفات البكسل الكبيرة بتسريع GPU. لـ 95% من مهام واجهة المستخدم، Core Graphics كافٍ.
استخدم CGImageSource لتحميل الصور المصغرة عبر createThumbnailAtIndex بدلاً من التحميل الكامل. لعرض الصور الكبيرة، أنشئ CGImage مع خيار الاختزال. حرر CGImage عبر CGImageRelease عندما لم يعد مطلوبًا.
نعم، يتضمن Core Graphics دعمًا كاملاً لـ PDF عبر CGPDFDocument للقراءة وCGPDFContext لإنشاء مستندات PDF. يمكنك رسم أي محتوى CGContext مباشرة في صفحة PDF مع الحفاظ على المتجهات.
يستخدم Core Graphics تلقائيًا دقة الجهاز عند الرسم على الشاشة. للسياقات غير المتصلة، استخدم UIGraphicsBeginImageContextWithOptions مع scale = 0 (مقياس النظام) أو حدد صراحة 2.0/3.0 لـ Retina/Retina HD.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.