Core Graphics — فریمورک رندرینگ 2D از اپل، بخشی از Core Foundation و قابل دسترس در iOS، macOS، tvOS و watchOS. این فریمورک C-API سطح پایین برای کار با گرافیک برداری و شطرنجی ارائه میدهد، از جمله رسم خطوط، گرادیانها، سایهها، تصاویر و متن. Core Graphics پایه UIKit، SwiftUI و AppKit است. طبق Apple Developer Documentation, 2026، این فریمورک در بیش از 90% برنامههای iOS استفاده میشود، زیرا هر عنصر قابل مشاهده از Core Graphics یا معادل سختافزاری آن عبور میکند.
نکات اصلی
Core Graphics (همچنین به عنوان Quartz 2D شناخته میشود) فریمورکی است که موتور گرافیکی 2D اپل را پیادهسازی میکند. این فریمورک بر پایه کتابخانه گرافیکی قابل حمل Quartz است و از مدل رسم مبتنی بر صفحه (page-based) استفاده میکند که در آن هر عمل یک دستور در دنبالهای شبیه به رسم روی کاغذ است. Core Graphics از ضدآلیاسینگ، شفافیت (alpha compositing) و فضاهای رنگی ICC پشتیبانی میکند.
معماری Core Graphics حول زمینه گرافیکی (CGContext) ساخته شده است که دستگاه خروجی هدف — صفحه نمایش، چاپگر، سند PDF یا بافر شطرنجی — را کپسوله میکند. زمینه تنظیمات جاری را مدیریت میکند: رنگ، ضخامت خط، تبدیل، ناحیه برش و فونتها. این رویکرد API یکسانی برای دستگاههای خروجی مختلف بدون تغییر کد رسم فراهم میکند.
Core Graphics عمدتاً روی CPU کار میکند و از مدل برداری (resolution-independent) استفاده میکند. این بدان معناست که خطوط و منحنیها در زمان رندرینگ با وضوح فعلی دستگاه شطرنجی میشوند. برخلاف Metal، Core Graphics نیاز به مدیریت صریح منابع GPU ندارد — سیستم تمام بهینهسازی را بر عهده میگیرد. برای بیشتر کارهای 2D (گرافیک، نمودارها، عناصر UI سفارشی)، عملکرد Core Graphics برای حفظ 60 FPS کافی است.
Core Graphics شامل حدود 50 نوع پایه (opaque types) است که هر کدام مسئول عملکرد خاصی هستند. همه انواع از قوانین مدیریت حافظه Core Foundation پیروی میکنند: با توابع حاوی Create در نام ایجاد میشوند، نیاز به فراخوانی CGRelease دارند و در Objective-C با ARC سازگار نیستند (البته Swift به طور خودکار حافظه را از طریق حاشیهنویسیهای CF_RETURNS_RETAINED مدیریت میکند).
CGContext — زمینه رسم، نوع مرکزی فریمورک. CGPath — مسیر برداری غیرقابل تغییر. CGColor — رنگ با مشخص کردن فضای رنگی. CGGradient — پر کردن گرادیانی. CGImage — تصویر شطرنجی. CGLayer — بافر آفلاین بهینهشده برای رسم تکراری. CGDataProvider — منبع داده برای تصاویر. CGColorSpace — فضای رنگی (sRGB، Display P3، Gray).
هر نوع برای حداقل سربار طراحی شده است: CGPath میتواند در حافظه پنهان ذخیره و بین زمینههای مختلف استفاده مجدد شود، CGColor هنگام ارسال به نمایش سختافزاری GPU تبدیل میشود، CGLayer محتوای از پیش شطرنجی شده را ذخیره میکند. چنین معماری به Core Graphics اجازه میدهد هم در کارهای ساده UI و هم در ویرایشگرهای گرافیکی حرفهای کارآمد عمل کند.
| نوع | کاربرد | مدیریت حافظه |
|---|---|---|
| CGContext | زمینه گرافیکی | CFRelease یا خودکار در Swift |
| CGPath | مسیر برداری | CFRelease (غیرقابل تغییر) |
| CGColor | رنگ در فضای رنگی | CFRelease یا CGColorCreate |
| CGImage | تصویر شطرنجی | CFRelease (پس از ایجاد) |
| CGLayer | بافر آفلاین | CFRelease یا CGLayerCreate |
CGPath — شی غیرقابل تغییری که دنبالهای از بخشهای هندسی را توصیف میکند: خطوط مستقیم، منحنیهای بزیه، کمانها و بستنها. برخلاف UIBezierPath، CGPath حاوی متدهای رسم نیست — فقط هندسه را ذخیره میکند. برای رسم، CGPath به زمینه اضافه میشود (CGContextAddPath) و سپس از طریق strokePath یا fillPath رسم میشود. غیرقابل تغییر بودن امنیت نخ و امکان ذخیره در حافظه پنهان را تضمین میکند.
CGPathCreateMutable یک مسیر قابل تغییر (CGMutablePathRef) برای ساخت مرحلهای ایجاد میکند. پس از مونتاژ نهایی، به CGPathRef غیرقابل تغییر تبدیل میشود. اپل توصیه میکند تعداد نقاط در CGPath را به حداقل برسانید — مسیرهای بیش از حد پیچیده (بیش از 1000 بخش) شطرنجی شدن را کند میکنند. برای بهینهسازی از CGPathCreateCopyBySimplifyingPath استفاده کنید که نقاط همخط اضافی را حذف میکند.
برای انیمیشن شکل بین دو CGPath میتوان از CABasicAnimation روی ویژگی path لایه CAShapeLayer استفاده کرد. محدودیت: هر دو CGPath باید تعداد بخشهای یکسانی داشته باشند (controls points). تابع 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) استفاده میکند که رنگ را در هر نقطه محاسبه میکند. این امکان ایجاد گرادیانهای پیچیده با انتقالهای غیرخطی و طرحهای رنگی ترکیبی را فراهم میکند.
برای رسم گرادیان درون یک شکل، برش (clip) روی مسیر آن شکل لازم است. ترتیب: مسیر را به زمینه اضافه کنید، 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 آن را یک بار شطرنجی میکند و سپس به سادگی در زمینه کپی میکند. طبق دادههای اپل، استفاده از CGLayer میتواند رسم تکراری را 2–5 برابر روی CPU و تا 10 برابر با شتاب سختافزاری加速 کند.
برای بارگذاری تصاویر از CGImageSource استفاده کنید — API قدرتمندی برای خواندن متاداده، تصاویر کوچک و فریمهای جداگانه از 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))
}
یک View سفارشی برای نمایش واترمارک روی تصویر با استفاده از 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 برای جلوگیری از مسدود شدن UI استفاده کنید.
سوالات متداول
UIKit — فریمورک UI سطح بالا که درون خود از Core Graphics برای رندرینگ استفاده میکند. Core Graphics — C-API سطح پایین برای گرافیک 2D. UIKit برای عناصر استاندارد راحتتر است، Core Graphics کنترل کامل روی هر پیکسل را فراهم میکند.
Core Graphics برای گرافیک 2D ایستا، نمودارها و عناصر UI سفارشی مناسب است. Metal — برای گرافیک 3D، انیمیشنهای پیچیده و پردازش آرایههای بزرگ پیکسل با شتاب GPU. برای 95% کارهای UI، Core Graphics کافی است.
از CGImageSource برای بارگذاری تصاویر کوچک از طریق createThumbnailAtIndex به جای بارگذاری کامل استفاده کنید. برای نمایش تصاویر بزرگ، CGImage با گزینه downsample ایجاد کنید. وقتی CGImage دیگر نیاز نیست، آن را از طریق CGImageRelease آزاد کنید.
بله، Core Graphics شامل پشتیبانی کامل از PDF از طریق CGPDFDocument برای خواندن و CGPDFContext برای ایجاد اسناد PDF است. میتوان هر محتوای CGContext را مستقیماً در صفحه PDF با حفظ بردارها رسم کرد.
Core Graphics به طور خودکار از وضوح دستگاه هنگام رندرینگ روی صفحه استفاده میکند. برای زمینههای آفلاین از UIGraphicsBeginImageContextWithOptions با پارامتر scale = 0 (مقیاس سیستم) استفاده کنید یا به طور صریح 2.0/3.0 برای Retina/Retina HD مشخص کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید