CGContext iOS और macOS में 2D ड्राइंग कमांड निष्पादित करने के लिए Core Graphics की मुख्य वस्तु है। यह एक ग्राफिकल कॉन्टेक्स्ट का प्रतिनिधित्व करता है जो वर्तमान स्थिति को संग्रहीत करता है: भरण रंग, रेखा मोटाई, रूपांतरण, क्लिपिंग क्षेत्र और फ़ॉन्ट। सभी ड्राइंग ऑपरेशन — रेखाएँ, आयत, टेक्स्ट, चित्र — CGContext के माध्यम से निष्पादित होते हैं। Apple Developer Documentation, 2026 के अनुसार, CGContext Apple पारिस्थितिकी तंत्र में सभी रास्टर और वेक्टर ग्राफिक्स की नींव है।
मुख्य बिंदु
CGContext Core Graphics फ्रेमवर्क से एक अपारदर्शी प्रकार (opaque type) है जो 2D रेंडरिंग कमांड निष्पादित करने के लिए वातावरण का प्रतिनिधित्व करता है। यह स्थिति स्टैक, वर्तमान रंग स्थान, निर्देशांक रूपांतरण और क्लिपिंग क्षेत्र का प्रबंधन करता है। CGContext एकमात्र वस्तु है जिसके साथ सभी Quartz 2D ड्राइंग फ़ंक्शन इंटरैक्ट करते हैं — कोई भी ग्राफिकल ऑपरेशन इसके माध्यम से गुज़रता है।
CGContext अपने उद्देश्य के आधार पर कई किस्मों में मौजूद है: bitmap context मेमोरी में रास्टर छवियों के साथ काम करने के लिए, PDF context PDF दस्तावेज़ उत्पन्न करने के लिए, window context स्क्रीन पर ड्राइंग के लिए (UIView द्वारा draw(_:) में प्रदान किया गया)। iOS डेवलपर अक्सर draw(_:) विधि के अंदर UIGraphicsGetCurrentContext() से या ऑफ़लाइन रेंडरिंग के लिए UIGraphicsBeginImageContextWithOptions से प्राप्त कॉन्टेक्स्ट के साथ काम करते हैं।
कॉन्टेक्स्ट सभी सेटिंग्स को स्थिति स्टैक के माध्यम से लागू करता है — डेवलपर वर्तमान स्थिति को सहेज (saveGState), पैरामीटर संशोधित कर सकता है और पिछली स्थिति को पुनर्स्थापित (restoreGState) कर सकता है। जटिल दृश्यों को बनाते समय यह अत्यंत महत्वपूर्ण है जहाँ विभिन्न तत्वों को अलग-अलग रंग, रेखा मोटाई और रूपांतरण की आवश्यकता होती है। Apple WWDC 2023 के अनुसार, स्थिति स्टैक का सही उपयोग कोड पठनीयता में सुधार करता है और दृश्य कलाकृतियों को रोकता है।
CGContextSaveGState कॉन्टेक्स्ट की वर्तमान स्थिति की एक प्रति स्टैक पर रखता है। इस स्थिति में सभी सेटिंग्स शामिल हैं: रंग, रेखा मोटाई, रूपांतरण, छाया, क्लिपिंग क्षेत्र, फ़ॉन्ट। पैरामीटर संशोधित करने के बाद, CGContextRestoreGState को कॉल करने से कॉन्टेक्स्ट सहेजी गई स्थिति पर लौट आता है, सभी मध्यवर्ती परिवर्तनों को पूर्ववत करता है। स्टैक iOS पर 32 स्थितियों तक धारण कर सकता है।
विभिन्न शैलियों वाले तत्वों के समूहों को बनाते समय (जैसे बहु-रंगीय चार्ट सेक्टर), स्थिति स्टैक प्रत्येक पैरामीटर को मैन्युअल रूप से याद रखने और पुनर्स्थापित करने की आवश्यकता को समाप्त करता है। saveGState/restoreGState के बिना, डेवलपर को प्रत्येक तत्व के बाद रंग, छाया और रूपांतरण को रीसेट करना होगा। स्टैक का उपयोग कोड को कम करता है और पुनर्स्थापना त्रुटियों को रोकता है।
सेव और रिस्टोर का संतुलन बनाए रखना महत्वपूर्ण है — प्रत्येक saveGState का एक मेल खाने वाला restoreGState होना चाहिए। संतुलन तोड़ने से स्थिति लीक या समय से पहले पुनर्स्थापना होती है, जो अप्रत्याशित रेंडरिंग का कारण बनती है। Xcode का स्थैतिक विश्लेषक CGContext स्टैक संतुलन की जाँच नहीं करता, इसलिए शुद्धता की जिम्मेदारी डेवलपर पर है। do/finally ब्लॉक में जोड़े को समूहित करने की सिफारिश की जाती है।
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
ctx.setStrokeColor(UIColor.red.cgColor)
ctx.setLineWidth(3)
ctx.addRect(CGRect(x: 50, y: 50, width: 200, height: 100))
ctx.strokePath()
ctx.restoreGState()
}
CGContextSetFillColorWithColor बाद के ऑपरेशनों के लिए भरण रंग सेट करता है। रंग CGColorRef के रूप में पास किया जाता है, जिसमें रंग स्थान और रंग घटकों के बारे में जानकारी होती है। CGContextSetStrokeColorWithColor स्ट्रोक रंग के लिए समान रूप से काम करता है। Apple बेहतर प्रदर्शन के लिए बार-बार उपयोग किए जाने वाले CGColorRef मानों को कैश करने की सिफारिश करता है।
CGContextDrawLinearGradient निर्दिष्ट रंगों के साथ दो बिंदुओं के बीच एक रैखिक ग्रेडिएंट बनाता है। CGContextDrawRadialGradient एक वृत्त से दूसरे वृत्त में संक्रमण करने वाला रेडियल ग्रेडिएंट बनाता है। ग्रेडिएंट के साथ काम करने के लिए, पहले CGGradientRef ऑब्जेक्ट बनाया जाता है जिसमें रंगों की एक सरणी और स्टॉप स्थितियाँ होती हैं। CGContext में ग्रेडिएंट RGB और Grayscale दोनों रंग स्थानों का समर्थन करते हैं।
ग्रेडिएंट के साथ क्षेत्र भरने के लिए पहले क्लिपिंग क्षेत्र सेट करना आवश्यक है। clip के बिना, ग्रेडिएंट पूरे कॉन्टेक्स्ट को भर देगा, न कि केवल वांछित आकृति को। विशिष्ट पैटर्न: कॉन्टेक्स्ट में पथ जोड़ें, क्षेत्र को प्रतिबंधित करने के लिए clip कॉल करें, फिर ग्रेडिएंट बनाएँ। यह पैटर्न सभी अनुप्रयोगों में उपयोग किया जाता है जहाँ जटिल आकृतियों के ग्रेडिएंट भरण की आवश्यकता होती है, बटन से लेकर पृष्ठभूमि तक।
| फ़ंक्शन | उद्देश्य | रंग स्थान |
|---|---|---|
| setFillColor | भरण रंग सेट करता है | कोई भी (CGColor के माध्यम से) |
| setStrokeColor | स्ट्रोक रंग सेट करता है | कोई भी (CGColor के माध्यम से) |
| drawLinearGradient | रैखिक ग्रेडिएंट बनाता है | RGB या Grayscale |
| drawRadialGradient | रेडियल ग्रेडिएंट बनाता है | RGB या Grayscale |
CGContextAddPath बाद के रेंडरिंग के लिए पहले से बनाए गए CGPathRef को कॉन्टेक्स्ट में जोड़ता है। पथ जोड़ने के बाद, इसे स्ट्रोक (strokePath), भरा (fillPath) या दोनों किया जा सकता है। CGContextBeginPath पिछले पथ को साफ़ करते हुए एक नया पथ शुरू करता है। कॉन्टेक्स्ट एक समय में केवल एक सक्रिय पथ का समर्थन करता है।
CGContextMoveToPoint वर्तमान आकृति बिंदु को निर्दिष्ट निर्देशांक पर ले जाता है। CGContextAddLineToPoint वर्तमान बिंदु से दिए गए बिंदु तक एक सीधी रेखा बनाता है। CGContextAddCurveToPoint एक घन बेज़ियर वक्र जोड़ता है, CGContextAddQuadCurveToPoint एक द्विघात वक्र जोड़ता है। CGContextClosePath अंतिम और पहले बिंदु के बीच एक सीधी रेखा के साथ आकृति को बंद करता है।
UIBezierPath के विपरीत, जहाँ ये सभी विधियाँ पथ ऑब्जेक्ट पर कॉल की जाती हैं, CGContext में ये सीधे कॉन्टेक्स्ट पर कॉल की जाती हैं। यह अंतर दृष्टिकोण चुनते समय मायने रखता है: UIBezierPath पथों के पुन: उपयोग के लिए अधिक सुविधाजनक है, CGContext न्यूनतम ओवरहेड के साथ एक बार के ड्राइंग के लिए बेहतर है। CGContext CGContextSetLineDash के माध्यम से डैश की गई रेखाओं, CGContextSetLineCap के माध्यम से लचीले सिरों और CGContextSetLineJoin के माध्यम से जोड़ों का भी समर्थन करता है।
let ctx = UIGraphicsGetCurrentContext()!
ctx.beginPath()
ctx.moveTo(x: 50, y: 100)
ctx.addLineTo(x: 200, y: 100)
ctx.addCurveTo(x1: 250, y1: 50, x2: 300, y2: 150, x3: 350, y3: 100)
ctx.setStrokeColor(UIColor.blue.cgColor)
ctx.setLineWidth(5)
ctx.strokePath()
CGContextClip ड्राइंग क्षेत्र को वर्तमान पथ तक सीमित करता है। सभी बाद के ड्राइंग ऑपरेशन केवल इस क्षेत्र के अंदर दिखाई देंगे। यह मास्किंग, कोनों को गोल करने और तत्वों की कस्टम सीमाएँ बनाने के लिए मूल तंत्र है। क्लिपिंग क्षेत्र saveGState/restoreGState के माध्यम से भी सहेजा और पुनर्स्थापित किया जाता है।
CGContextTranslateCTM कॉन्टेक्स्ट निर्देशांक प्रणाली के मूल बिंदु को स्थानांतरित करता है। CGContextScaleCTM X और Y अक्षों को स्केल करता है। CGContextRotateCTM निर्देशांक प्रणाली को वर्तमान मूल बिंदु के चारों ओर घुमाता है। रूपांतरण संचित होते हैं — प्रत्येक बाद वाला वर्तमान निर्देशांक प्रणाली के सापेक्ष लागू होता है। मिश्रित रूपांतरण (स्थानांतरण + घुमाव + स्केल) एनीमेशन और तत्व स्थिति निर्धारण के लिए उपयोग किए जाते हैं।
क्लिपिंग और रूपांतरण का संयुक्त उपयोग शक्तिशाली क्षमताएँ प्रदान करता है: क्लिपिंग के माध्यम से एक जटिल मास्क बनाया जा सकता है, फिर पूरी सामग्री पर रूपांतरण लागू किया जा सकता है। एक विशिष्ट उदाहरण — गोल कोनों के साथ एक कोण पर छवि का भाग प्रदर्शित करना। संचालन का क्रम महत्वपूर्ण है: पहले क्लिपिंग क्षेत्र सेट करें, फिर रूपांतरण लागू करें, फिर सामग्री बनाएँ। Apple ड्राइंग लूप में CTM (वर्तमान रूपांतरण मैट्रिक्स) परिवर्तनों को कम करने की सिफारिश करता है।
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
// clipping region - circle
ctx.addEllipse(in: CGRect(x: 50, y: 50, width: 200, height: 200))
ctx.clip()
// content transformation
ctx.translateBy(x: 150, y: 150)
ctx.rotate(by: .pi / 4)
ctx.translateBy(x: -150, y: -150)
UIImage(named: "photo")?.draw(at: CGPoint(x: 50, y: 50))
ctx.restoreGState()
}
CGContext का उपयोग करके ग्रेडिएंट चार्ट बनाने का एक पूर्ण उदाहरण देखें। चार्ट में शामिल हैं ग्रेडिएंट भरण और टेक्स्ट लेबल के साथ तीन अलग-अलग रंगों के सेक्टर। कोड एक ही कॉन्टेक्स्ट में saveGState, clip, ग्रेडिएंट और टेक्स्ट रेंडरिंग के संयोजन को प्रदर्शित करता है।
class PieChartView: UIView {
private struct Slice {
let color: UIColor
let value: CGFloat
let label: String
}
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
let slices = [
Slice(color: .systemRed, value: 0.4, label: "iOS"),
Slice(color: .systemGreen, value: 0.35, label: "Android"),
Slice(color: .systemBlue, value: 0.25, label: "Other")
]
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = bounds.width * 0.35
var startAngle: CGFloat = -.pi / 2
for slice in slices {
let endAngle = startAngle + .pi * 2 * slice.value
ctx.saveGState()
ctx.moveTo(x: center.x, y: center.y)
ctx.addArc(center: center, radius: radius,
startAngle: startAngle, endAngle: endAngle, clockwise: false)
ctx.closePath()
ctx.setFillColor(slice.color.cgColor)
ctx.fillPath()
// text label
let midAngle = startAngle + endAngle / 2
let labelPos = CGPoint(
x: center.x + radius * 0.7 * cos(midAngle),
y: center.y + radius * 0.7 * sin(midAngle)
)
slice.label.draw(at: labelPos, withAttributes: [
.foregroundColor: UIColor.white,
.font: UIFont.boldSystemFont(ofSize: 14)
])
ctx.restoreGState()
startAngle = endAngle
}
}
}
इस उदाहरण में, चार्ट का प्रत्येक सेक्टर अपने स्वयं के saveGState/restoreGState ब्लॉक में बनाया गया है। यह दृष्टिकोण गारंटी देता है कि एक सेक्टर के रंग और पथ सेटिंग्स दूसरों को प्रभावित नहीं करते। addArc विधि प्रारंभ से अंत कोण तक एक चाप बनाती है, और closePath सेक्टर को केंद्र की ओर बंद करता है। लेबल टेक्स्ट को स्थिति गणना के लिए त्रिकोणमितीय फ़ंक्शन cos और sin का उपयोग करके सेक्टर के मध्य कोण पर रखा जाता है।
बार-बार पुनः ड्राइंग के दौरान प्रदर्शन में सुधार के लिए, कोण और स्थिति गणनाओं को एक अलग सरणी में कैश करने की सिफारिश की जाती है। CGContext सभी ऑपरेशन CPU पर निष्पादित करता है, इसलिए दर्जनों सेक्टर वाले जटिल दृश्यों में अनुकूलन की आवश्यकता हो सकती है — उदाहरण के लिए, CGLayer में पूर्व-रेंडरिंग या GPU त्वरण के लिए Metal का उपयोग। 5–10 तत्वों वाले अधिकांश UI कार्यों के लिए, CGContext का प्रदर्शन स्वीकार्य बना रहता है।
अक्सर पूछे जाने वाले प्रश्न
UIView के draw(_:) विधि के अंदर या UIGraphicsBeginImageContextWithOptions ब्लॉक के अंदर UIGraphicsGetCurrentContext() को कॉल करें। CALayer परतों के लिए, CALayerDelegate की draw(in:) विधि का उपयोग करें, जो एक तैयार कॉन्टेक्स्ट प्राप्त करती है।
fillPath वर्तमान पथ के आंतरिक भाग को setFillColor के रंग से भरता है। strokePath setStrokeColor, setLineWidth और setLineCap के पैरामीटर के साथ पथ के साथ एक रेखा बनाता है। दोनों ऑपरेशन क्रमिक रूप से निष्पादित होते हैं: पहले भरण, फिर यदि आवश्यक हो तो स्ट्रोक।
Bitmap CGContext CGBitmapContextCreate के माध्यम से बनाया गया एक कॉन्टेक्स्ट है जो स्क्रीन के बजाय मेमोरी बफर में बनाता है। इसका उपयोग पृष्ठभूमि छवि निर्माण, प्रदर्शन के बिना ग्राफिक्स प्रसंस्करण और Metal या OpenGL के लिए टेक्सचर बनाने के लिए किया जाता है।
Core Graphics सभी सेटिंग्स को रीसेट करने की विधि प्रदान नहीं करता है। परिवर्तनों से पहले saveGState और मूल स्थिति पर लौटने के लिए restoreGState का उपयोग करें। वैकल्पिक रूप से, समान पैरामीटर के साथ एक नया कॉन्टेक्स्ट बनाएँ।
drawLinearGradient को कॉल करने से पहले, वांछित पथ पर clip के माध्यम से क्लिपिंग क्षेत्र सेट करें। clip के बिना, ग्रेडिएंट पूरे कॉन्टेक्स्ट को भरता है। क्रम: addPath → clip → drawLinearGradient — आकृति के अंदर ग्रेडिएंट की गारंटी देता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें