Core Graphics — คืออะไร หลักการทำงานและเฟรมเวิร์กสำหรับกราฟิก 2D

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-21 เวลาอ่าน: 10 นาที

Core Graphics คือเฟรมเวิร์กการเรนเดอร์ 2D ของ Apple ซึ่งเป็นส่วนหนึ่งของ Core Foundation ที่พร้อมใช้งานบน iOS, macOS, tvOS และ watchOS โดยมี API ภาษา C ระดับต่ำสำหรับทำงานกับกราฟิกเวกเตอร์และแรสเตอร์ รวมถึงการวาดเส้นทาง เกรเดียนต์ เงา รูปภาพ และข้อความ Core Graphics ทำหน้าที่เป็นพื้นฐานสำหรับ UIKit, SwiftUI และ AppKit ตาม Apple Developer Documentation, 2026 เฟรมเวิร์กนี้ถูกใช้ในมากกว่า 90% ของแอป iOS เนื่องจากทุกองค์ประกอบที่มองเห็นได้ต้องผ่าน Core Graphics หรืออุปกรณ์เทียบเท่าทางฮาร์ดแวร์

ประเด็นสำคัญ

  • Core Graphics คือเฟรมเวิร์ก 2D พื้นฐานของ Apple สำหรับการเรนเดอร์เวกเตอร์และแรสเตอร์
  • CGContext คือออบเจ็กต์กลางของเฟรมเวิร์กซึ่งดำเนินการวาดทั้งหมดผ่านมัน
  • CGPath คือเส้นทางเวกเตอร์ที่ไม่เปลี่ยนรูปสำหรับนำมาใช้ซ้ำในบริบทต่างๆ
  • CGGradient คือออบเจ็กต์สำหรับสร้างเกรเดียนต์เชิงเส้นและรัศมีพร้อมรองรับพื้นที่สี
  • CGImage คือภาพแรสเตอร์ที่สามารถวาด แปลง และมาสก์ได้

Core Graphics คืออะไร?

Core Graphics (หรือที่รู้จักในชื่อ Quartz 2D) คือเฟรมเวิร์กที่ implement เอนจินกราฟิก 2D ของ Apple ซึ่งอาศัยไลบรารีกราฟิกแบบพกพา Quartz และใช้โมเดลการวาดแบบหน้า ซึ่งแต่ละการกระทำคือคำสั่งในลำดับที่คล้ายกับการวาดบนกระดาษ Core Graphics รองรับการป้องกันรอยหยัก ความโปร่งใส (การคอมโพสิตอัลฟา) และพื้นที่สี ICC

สถาปัตยกรรมของ Core Graphics สร้างขึ้นรอบ บริบทกราฟิก (CGContext) ซึ่งห่อหุ้มอุปกรณ์เอาต์พุตเป้าหมาย — หน้าจอ เครื่องพิมพ์ เอกสาร PDF หรือบัฟเฟอร์แรสเตอร์ บริบทจัดการการตั้งค่าปัจจุบัน: สี ความหนาของเส้น การแปลง พื้นที่ตัด และฟอนต์ วิธีการนี้ให้ API ที่เป็นหนึ่งเดียวสำหรับอุปกรณ์เอาต์พุตต่างๆ โดยไม่ต้องเปลี่ยนโค้ดการวาด

Core Graphics ทำงานบน CPU เป็นหลัก โดยใช้โมเดลเวกเตอร์ (ไม่ขึ้นกับความละเอียด) ซึ่งหมายความว่าเส้นและเส้นโค้งจะถูกแรสเตอร์ที่ความละเอียดของอุปกรณ์ปัจจุบันเมื่อวาด แตกต่างจาก Metal Core Graphics ไม่ต้องการการจัดการทรัพยากร GPU อย่างชัดเจน — ระบบจัดการการปรับแต่งทั้งหมดเอง สำหรับงาน 2D ส่วนใหญ่ (กราฟิก แผนภูมิ องค์ประกอบ UI ที่กำหนดเอง) ประสิทธิภาพของ Core Graphics เพียงพอที่จะรักษา 60 FPS

สถาปัตยกรรมและประเภทหลัก

Core Graphics ประกอบด้วยประมาณ 50 ประเภทพื้นฐาน (ประเภททึบแสง) ซึ่งแต่ละประเภทรับผิดชอบฟังก์ชันการทำงานเฉพาะ ทุกประเภทปฏิบัติตามกฎการจัดการหน่วยความจำของ Core Foundation: ถูกสร้างขึ้นผ่านฟังก์ชันที่มี Create ในชื่อ ต้องการการเรียก CGRelease และไม่เข้ากันได้กับ ARC ใน Objective-C (อย่างไรก็ตาม Swift จัดการหน่วยความจำโดยอัตโนมัติผ่านคำอธิบายประกอบ CF_RETURNS_RETAINED)

ประเภทหลักของ Core Graphics

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: เส้นทางเวกเตอร์และการเพิ่มประสิทธิภาพ

CGPath คือออบเจ็กต์ที่ไม่เปลี่ยนรูปซึ่งอธิบายลำดับของส่วนเรขาคณิต: เส้นตรง เส้นโค้งเบซิเอร์ ส่วนโค้ง และการปิด แตกต่างจาก UIBezierPath ตรงที่ CGPath ไม่มีเมธอดการวาด — มันเก็บเฉพาะเรขาคณิต ในการวาด CGPath จะถูกเพิ่มไปยังบริบท (CGContextAddPath) แล้วเรนเดอร์ผ่าน strokePath หรือ fillPath ความไม่เปลี่ยนรูปช่วยรับประกันความปลอดภัยของเธรดและความสามารถในการแคช

การสร้างและเพิ่มประสิทธิภาพเส้นทาง

CGPathCreateMutable สร้างเส้นทางที่เปลี่ยนแปลงได้ (CGMutablePathRef) สำหรับการสร้างทีละขั้น หลังจากการประกอบสุดท้าย มันจะถูกแปลงเป็น CGPathRef ที่ไม่เปลี่ยนรูป Apple แนะนำให้ลดจำนวนจุดใน CGPath — เส้นทางที่ซับซ้อนเกินไป (มากกว่า 1,000 ส่วน) ทำให้การแรสเตอร์ช้าลง สำหรับการเพิ่มประสิทธิภาพ ให้ใช้ CGPathCreateCopyBySimplifyingPath ซึ่งลบจุดที่ซ้ำซ้อนที่อยู่บนเส้นตรงเดียวกัน

สำหรับการเคลื่อนไหวรูปร่างระหว่างออบเจ็กต์ CGPath สองตัว คุณสามารถใช้ CABasicAnimation บนคุณสมบัติ path ของ CAShapeLayer ข้อจำกัด: CGPath ทั้งสองต้องมีจำนวนส่วนเท่ากัน (จุดควบคุม) ฟังก์ชัน CGPathApply ช่วยให้คุณ遍历องค์ประกอบทั้งหมดของเส้นทางและเปรียบเทียบโครงสร้างของมัน ถ้าส่วนไม่ตรงกัน การเคลื่อนไหวจะกระตุก — ในกรณีนี้ ให้ใช้ CADisplayLink สำหรับการประมาณค่าจุดด้วยตนเอง

swift
// สร้างเส้นทางที่เปลี่ยนแปลงได้
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 และ CGShading

CGGradient คือออบเจ็กต์ที่กำหนดการเปลี่ยนแปลงอย่างราบรื่นระหว่างสีสองสีขึ้นไปตามเส้นตรง (เกรเดียนต์เชิงเส้น) หรือจากศูนย์กลางออกไปด้านนอก (เกรเดียนต์รัศมี) CGGradient ถูกสร้างขึ้นด้วยพื้นที่สีที่ระบุ อาร์เรย์ของ CGColorRef และอาร์เรย์ของตำแหน่งหยุดจาก 0.0 ถึง 1.0 หลังจากการสร้าง เกรเดียนต์สามารถนำมาใช้ซ้ำได้หลายครั้งในบริบทต่างๆ

CGShading สำหรับเกรเดียนต์ขั้นสูง

CGShading เป็นกลไกที่ทรงพลังกว่าที่ช่วยให้กำหนดฟังก์ชันการเปลี่ยนสีตามเส้นทาง แตกต่างจาก CGGradient ที่ทำงานกับชุดสีที่ตายตัว CGShading ใช้ฟังก์ชัน callback (CGFunctionRef) ที่คำนวณสีในแต่ละจุด ซึ่งช่วยให้สร้างเกรเดียนต์ที่ซับซ้อนด้วยการเปลี่ยนแปลงที่ไม่เป็นเชิงเส้นและแบบแผนสีแบบผสม

ในการวาดเกรเดียนต์ภายในรูปทรง จำเป็นต้องมี คลิป บนเส้นทางของรูปทรงนั้น ลำดับ: เพิ่มเส้นทางไปยังบริบท เรียก CGContextClip จากนั้นวาดเกรเดียนต์ หากไม่มีคลิป เกรเดียนต์จะเติมเต็มทั้งบริบท บน iOS แนะนำให้ใช้ CGGradient เป็นตัวเลือกที่ง่ายกว่าและมีประสิทธิภาพมากกว่า — CGShading เหมาะสมสำหรับฟังก์ชันสีที่กำหนดเองเท่านั้น

swift
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 และ CGLayer

CGImage คือภาพแรสเตอร์ใน Core Graphics ที่สามารถโหลดจากไฟล์ สร้างโดยโปรแกรม หรือได้รับจาก UIImage CGImage ประกอบด้วยข้อมูลพิกเซล ข้อมูลพื้นที่สี ขนาด ความลึกบิต และการจัดเรียงข้อมูล แตกต่างจาก UIImage ตรงที่ CGImage ไม่จัดการการปรับขนาด Retina — ความรับผิดชอบนี้ตกอยู่กับนักพัฒนาผ่านพารามิเตอร์ scale

CGLayer — การเพิ่มประสิทธิภาพการวาดซ้ำ

CGLayer คือบัฟเฟอร์ออฟไลน์สำหรับการแรสเตอร์เนื้อหาคงที่ล่วงหน้า หากชุดคำสั่งวาดชุดเดียวกันถูกดำเนินการซ้ำๆ (เช่น ลวดลายพื้นหลัง) CGLayer จะแรสเตอร์มันครั้งเดียวแล้วคัดลอกไปยังบริบท ตามข้อมูลของ Apple การใช้ CGLayer สามารถเร่งการวาดซ้ำได้ 2–5 เท่าบน CPU และสูงถึง 10 เท่าด้วยการเร่งด้วยฮาร์ดแวร์

สำหรับการโหลดรูปภาพ ให้ใช้ CGImageSource — API ที่ทรงพลังสำหรับอ่านข้อมูลเมตา ภาพขนาดย่อ และเฟรมแต่ละเฟรมจาก GIF/APNG CGImageSource รองรับการโหลดแบบก้าวหน้าและการดึงเฉพาะส่วนที่จำเป็น เมื่อทำงานกับภาพขนาดใหญ่ (เกินขนาดหน้าจอ) แนะนำให้สร้าง CGImageSource พร้อมแคชบนดิสก์และใช้ CGImageSourceCreateThumbnailAtIndex เพื่อแสดงเวอร์ชันที่ลดขนาด

swift
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

มาสร้าง View ที่กำหนดเองสำหรับแสดงลายน้ำบนภาพโดยใช้ Core Graphics ลายน้ำประกอบด้วย ข้อความโปร่งแสงและโลโก้เวกเตอร์ที่วางซ้อนบนภาพต้นฉบับ โค้ดสาธิตการทำงานกับ CGContext, CGImage, ข้อความ และความโปร่งใสในบริบทเดียว

swift
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

คำถามที่พบบ่อย

Core Graphics แตกต่างจาก UIKit อย่างไร?

UIKit คือเฟรมเวิร์ก UI ระดับสูงที่ใช้ Core Graphics ภายในสำหรับการวาด Core Graphics คือ API ภาษา C ระดับต่ำสำหรับกราฟิก 2D UIKit สะดวกกว่าสำหรับองค์ประกอบมาตรฐาน ในขณะที่ Core Graphics ให้ควบคุมทุกพิกเซลอย่างสมบูรณ์

เมื่อใดควรใช้ Core Graphics แทน Metal?

Core Graphics เหมาะสำหรับกราฟิก 2D แบบคงที่ แผนภูมิ และองค์ประกอบ UI ที่กำหนดเอง Metal เหมาะสำหรับกราฟิก 3D อนิเมชันที่ซับซ้อน และการประมวลผลอาร์เรย์พิกเซลขนาดใหญ่ด้วยการเร่ง GPU สำหรับ 95% ของงาน UI Core Graphics ก็เพียงพอ

จะประหยัดหน่วยความจำเมื่อทำงานกับ CGImage ได้อย่างไร?

ใช้ CGImageSource เพื่อโหลดภาพขนาดย่อผ่าน createThumbnailAtIndex แทนการโหลดทั้งหมด ในการแสดงภาพขนาดใหญ่ ให้สร้าง CGImage พร้อมตัวเลือกลดตัวอย่าง ปล่อย CGImage ผ่าน CGImageRelease เมื่อไม่ต้องการใช้อีก

Core Graphics รองรับ PDF หรือไม่?

ใช่ Core Graphics รวมการรองรับ PDF อย่างสมบูรณ์ผ่าน CGPDFDocument สำหรับการอ่านและ CGPDFContext สำหรับการสร้างเอกสาร PDF คุณสามารถวาดเนื้อหา CGContext ใดๆ ลงในหน้า PDF โดยตรงโดยคงเวกเตอร์ไว้

จะรับประกันคุณภาพ Retina เมื่อวาดได้อย่างไร?

Core Graphics ใช้ความละเอียดของอุปกรณ์โดยอัตโนมัติเมื่อวาดบนหน้าจอ สำหรับบริบทออฟไลน์ ให้ใช้ UIGraphicsBeginImageContextWithOptions ด้วย scale = 0 (สเกลระบบ) หรือระบุ 2.0/3.0 สำหรับ Retina/Retina HD อย่างชัดเจน

สรุป

  • Core Graphics คือเฟรมเวิร์ก 2D พื้นฐานของ Apple สำหรับการเรนเดอร์เวกเตอร์และแรสเตอร์บน CPU
  • CGContext คือออบเจ็กต์กลางที่จัดการสแต็กสถานะและอุปกรณ์เอาต์พุตเป้าหมาย
  • CGPath ให้เส้นทางเวกเตอร์ที่ไม่เปลี่ยนรูปสำหรับการแคชที่ปลอดภัยและการนำมาใช้ซ้ำอย่างปลอดภัยในเธรด
  • CGGradient และ CGShading ให้กลไกสำหรับสร้างเกรเดียนต์เชิงเส้น รัศมี และฟังก์ชัน
  • CGImage ให้ภาพแรสเตอร์พร้อมรองรับพื้นที่สีและความลึกบิตต่างๆ
  • CGLayer คือบัฟเฟอร์ออฟไลน์ที่เร่งการวาดซ้ำ 2–5 เท่า
  • Core Graphics ทำหน้าที่เป็นพื้นฐานสำหรับ UIKit, SwiftUI และ AppKit — ทุกองค์ประกอบที่มองเห็นได้ใน iOS ผ่านมัน

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม