Core Graphics é o framework de renderização 2D da Apple, parte do Core Foundation, disponível no iOS, macOS, tvOS e watchOS. Ele fornece uma API C de baixo nível para trabalhar com gráficos vetoriais e raster, incluindo desenho de contornos, gradientes, sombras, imagens e texto. Core Graphics serve como base para UIKit, SwiftUI e AppKit. De acordo com Apple Developer Documentation, 2026, o framework é usado em mais de 90% dos aplicativos iOS, porque cada elemento visível passa pelo Core Graphics ou seu equivalente de hardware.
Principais pontos
Core Graphics (também conhecido como Quartz 2D) é um framework que implementa o motor gráfico 2D da Apple. É baseado na biblioteca portátil de gráficos Quartz e usa um modelo de desenho baseado em página, onde cada ação é um comando em uma sequência semelhante a desenhar no papel. Core Graphics suporta anti-aliasing, transparência (composição alfa) e espaços de cor ICC.
A arquitetura do Core Graphics é construída em torno de um contexto gráfico (CGContext) que encapsula o dispositivo de saída alvo — tela, impressora, documento PDF ou buffer raster. O contexto gerencia as configurações atuais: cor, espessura da linha, transformação, área de recorte e fontes. Esta abordagem fornece uma API uniforme para diferentes dispositivos de saída sem alterar o código de desenho.
Core Graphics funciona principalmente na CPU, usando um modelo vetorial (independente de resolução). Isso significa que linhas e curvas são rasterizadas na resolução atual do dispositivo ao serem desenhadas. Ao contrário do Metal, Core Graphics não requer gerenciamento explícito de recursos GPU — o sistema cuida de toda a otimização. Para a maioria das tarefas 2D (gráficos, diagramas, elementos de UI personalizados), o desempenho do Core Graphics é suficiente para manter 60 FPS.
Core Graphics inclui cerca de 50 tipos base (tipos opacos), cada um responsável por uma funcionalidade específica. Todos os tipos seguem as regras de gerenciamento de memória do Core Foundation: são criados através de funções com Create no nome, requerem uma chamada a CGRelease e não são compatíveis com ARC em Objective-C (no entanto, o Swift gerencia a memória automaticamente através de anotações CF_RETURNS_RETAINED).
CGContext — o contexto de desenho, o tipo central do framework. CGPath — um contorno vetorial imutável. CGColor — uma cor com um espaço de cor especificado. CGGradient — um preenchimento gradiente. CGImage — uma imagem raster. CGLayer — um buffer offline otimizado para desenho repetitivo. CGDataProvider — uma fonte de dados para imagens. CGColorSpace — um espaço de cor (sRGB, Display P3, Gray).
Cada tipo é projetado para sobrecarga mínima: CGPath pode ser armazenado em cache e reutilizado entre diferentes contextos, CGColor é convertido para representação de hardware GPU ao ser passado, CGLayer armazena conteúdo pré-rasterizado. Esta arquitetura permite que Core Graphics funcione eficientemente tanto em tarefas simples de UI quanto em editores gráficos profissionais.
| Tipo | Propósito | Gerenciamento de memória |
|---|---|---|
| CGContext | Contexto gráfico | CFRelease ou automático em Swift |
| CGPath | Contorno vetorial | CFRelease (imutável) |
| CGColor | Cor em espaço de cor | CFRelease ou CGColorCreate |
| CGImage | Imagem raster | CFRelease (após criação) |
| CGLayer | Buffer offline | CFRelease ou CGLayerCreate |
CGPath é um objeto imutável que descreve uma sequência de segmentos geométricos: linhas retas, curvas Bezier, arcos e fechamentos. Ao contrário do UIBezierPath, CGPath não contém métodos de desenho — ele apenas armazena a geometria. Para desenhar, CGPath é adicionado ao contexto (CGContextAddPath) e então renderizado através de strokePath ou fillPath. A imutabilidade garante segurança em threads e capacidade de cache.
CGPathCreateMutable cria um caminho mutável (CGMutablePathRef) para construção passo a passo. Após a montagem final, ele é convertido em um CGPathRef imutável. A Apple recomenda minimizar o número de pontos em CGPath — contornos muito complexos (mais de 1000 segmentos) retardam a rasterização. Para otimização, use CGPathCreateCopyBySimplifyingPath, que remove pontos colineares redundantes.
Para animar a forma entre dois objetos CGPath, você pode usar CABasicAnimation na propriedade path do CAShapeLayer. Limitação: ambos os CGPath devem ter o mesmo número de segmentos (pontos de controle). A função CGPathApply permite percorrer todos os elementos do caminho e comparar sua estrutura. Se os segmentos não coincidirem, a animação será irregular — neste caso, use CADisplayLink para interpolação manual de pontos.
// criar caminho mutável
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()
// converter para imutável para cache seguro
let immutablePath: CGPath = mutablePath
CATransaction.perform {
shapeLayer.path = immutablePath
}
CGGradient é um objeto que define uma transição suave entre duas ou mais cores ao longo de uma linha reta (gradiente linear) ou do centro para as bordas (gradiente radial). CGGradient é criado com um espaço de cor especificado, um array de CGColorRef e um array de posições de parada de 0.0 a 1.0. Após a criação, o gradiente pode ser reutilizado várias vezes em diferentes contextos.
CGShading é um mecanismo mais poderoso que permite definir uma função de mudança de cor ao longo de um caminho. Ao contrário do CGGradient, que trabalha com um conjunto fixo de cores, CGShading usa uma função de retorno (CGFunctionRef) que calcula a cor em cada ponto. Isso permite criar gradientes complexos com transições não lineares e esquemas de cores compostos.
Para desenhar um gradiente dentro de uma forma, é necessário um clip no contorno dessa forma. A ordem: adicionar o caminho ao contexto, chamar CGContextClip, depois desenhar o gradiente. Sem clip, o gradiente preenche todo o contexto. No iOS, recomenda-se CGGradient como a opção mais simples e eficiente — CGShading só se justifica para funções de cor personalizadas.
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 é uma imagem raster no Core Graphics que pode ser carregada de um arquivo, criada programaticamente ou obtida de UIImage. CGImage contém dados de pixel, informações de espaço de cor, tamanho, profundidade de bits e disposição de dados. Ao contrário do UIImage, CGImage não gerencia o escalonamento Retina — esta responsabilidade recai sobre o desenvolvedor através do parâmetro scale.
CGLayer é um buffer offline para pré-rasterização de conteúdo estático. Se o mesmo conjunto de comandos de desenho for executado repetidamente (por exemplo, um padrão de fundo), CGLayer o rasteriza uma vez e depois simplesmente o copia para o contexto. De acordo com a Apple, o uso de CGLayer pode acelerar o desenho repetitivo em 2–5 vezes na CPU e até 10 vezes com aceleração de hardware.
Para carregar imagens, use CGImageSource — uma API poderosa para ler metadados, miniaturas e quadros individuais de GIF/APNG. CGImageSource permite carregamento progressivo e recuperação apenas dos fragmentos necessários. Ao trabalhar com imagens grandes (excedendo o tamanho da tela), recomenda-se criar um CGImageSource com cache em disco e usar CGImageSourceCreateThumbnailAtIndex para exibir uma versão reduzida.
func createLayer(ctx: CGContext, size: CGSize) -> CGLayer? {
guard let layer = CGLayer(ctx, size: size, auxiliaryInfo: nil) else { return nil }
let layerCtx = layer.context !
// desenhar uma vez
layerCtx.setFillColor(UIColor.lightGray.cgColor)
layerCtx.addEllipse(in: CGRect(origin: .zero, size: size))
layerCtx.fillPath()
return layer
}
// uso em draw()
for i in 0..<20 {
ctx.draw(layer, at: CGPoint(x: CGFloat(i) * 30, y: 0))
}
Vamos construir uma View personalizada para exibir uma marca d'água em uma imagem usando Core Graphics. A marca d'água inclui texto semitransparente e um logotipo vetorial sobrepostos à imagem original. O código demonstra o trabalho com CGContext, CGImage, texto e transparência em um único contexto.
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 }
// desenhar imagem de fundo
UIImage(named: "background")?.draw(in: rect)
// configurar transparência da marca d'água
ctx.saveGState()
ctx.translateBy(x: rect.midX, y: rect.midY)
ctx.rotate(by: -.pi / 6)
// texto semitransparente
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
)
// ícone vetorial (círculo com cruz) abaixo do texto
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()
}
}
O código usa recursos chave do Core Graphics: saveGState/restoreGState para isolar os efeitos da marca d'água do fundo, translateBy e rotate para posicionamento e rotação, texto semitransparente através de withAlphaComponent e um ícone vetorial através de addEllipse e addLineTo. Toda a marca d'água é desenhada como uma composição única após a imagem de fundo.
Ao criar marcas d'água para fotos em produção, é importante considerar o desempenho. Se a imagem for maior que a tela, reduza-a usando CGImageSourceCreateThumbnailAtIndex antes de aplicar a marca d'água. Core Graphics lida com todas as operações na CPU — para processamento em lote de dezenas de imagens, use uma fila em segundo plano e CGBitmapContext para evitar bloquear a UI.
Perguntas frequentes
UIKit é um framework de UI de alto nível que usa Core Graphics internamente para desenho. Core Graphics é uma API C de baixo nível para gráficos 2D. UIKit é mais conveniente para elementos padrão, enquanto Core Graphics dá controle total sobre cada pixel.
Core Graphics é adequado para gráficos 2D estáticos, diagramas e elementos de UI personalizados. Metal é para gráficos 3D, animações complexas e processamento de grandes matrizes de pixels com aceleração GPU. Para 95% das tarefas de UI, Core Graphics é suficiente.
Use CGImageSource para carregar miniaturas através de createThumbnailAtIndex em vez do carregamento completo. Para exibir imagens grandes, crie CGImage com a opção de downsampling. Libere CGImage através de CGImageRelease quando não for mais necessário.
Sim, Core Graphics inclui suporte completo a PDF através de CGPDFDocument para leitura e CGPDFContext para criação de documentos PDF. Você pode desenhar qualquer conteúdo CGContext diretamente em uma página PDF preservando os vetores.
Core Graphics usa automaticamente a resolução do dispositivo ao desenhar na tela. Para contextos offline, use UIGraphicsBeginImageContextWithOptions com scale = 0 (escala do sistema) ou especifique explicitamente 2.0/3.0 para Retina/Retina HD.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também