低级别图像对象CGImage
低级别图像对象CGImage

低级别图像对象CGImage

CGImage 简介

CGImage(Core Graphics Image) 是 Core Graphics 框架中的一个低级别图像对象,表示位图图像的数据。它是一个不可变的对象,主要用于处理和显示位图数据,支持像素级的图像操作。

CGImage 的特点

1、不可变性

CGImage 表示的图像数据是不可变的,不能直接修改。

如果需要更改图像内容,通常需要创建新的 CGImage 对象。

设计初衷:不可变对象更易于管理,因为它们在多线程环境中是安全的,避免了数据竞争。

性能考虑:不可变对象更高效,尤其是在需要缓存或重复渲染时。

2、支持像素操作

包括颜色空间、位深度、透明度等详细属性。

可以直接访问每个像素的数据,用于精细的图像处理。

精细控制:当需要直接操作图像的像素时,CGImage 是一个理想的选择。例如,手动调整像素值来应用自定义效果。

灵活性:通过访问颜色空间、位深度等属性,可以适应各种图像格式需求。

3、与 UIImage 的关系

UIImage 是 UIKit 提供的高层抽象,通常封装了 CGImage。

通过 UIImage 的 cgImage 属性,可以获取底层的 CGImage。

桥接高层与底层:UIImage 提供了图像显示的便利,而 CGImage 提供了底层操作的能力。

灵活性:可以从 UIImage 获取 CGImage 以执行高级操作,然后将处理后的 CGImage 转换回 UIImage。

CGImage 的构成

CGImage 由以下属性构成:

1、宽度和高度

图像的像素宽度和高度,决定图像的分辨率和大小。

if let cgImage = UIImage(named: "example")?.cgImage {
    print("Width: \(cgImage.width), Height: \(cgImage.height)") // Width: 1920, Height: 1080
}

2、颜色空间

定义像素数据如何被解释,例如 RGB、CMYK和Gray。

if let cgImage = UIImage(named: "example")?.cgImage {
    print("Color Space: \(String(describing: cgImage.colorSpace))") // Color Space: Optional(kCGColorSpaceSRGB)
}

3、位深度

每个颜色分量的位数(如 8 位表示 256 种颜色,16位表示每个分量占用16位,用于高动态范围(HDR)图像,1位表示黑白图像 ),决定图像的颜色范围和细节。

if let cgImage = UIImage(named: "example")?.cgImage {
    print("Bits per Component: \(cgImage.bitsPerComponent)")    // Bits per Component: 8
}

4、Alpha 通道

是否包含透明度信息,一个像素的 Alpha 值通常范围为 0(完全透明)到 1(完全不透明)。

带有 Alpha:支持透明度,适合需要叠加效果的图像。无 Alpha:所有像素都是不透明的。

if let cgImage = UIImage(named: "example")?.cgImage {
    print("Contains Alpha: \(cgImage.alphaInfo != .none)")  // Contains Alpha: true
}

5、数据缓冲区

存储图像像素的实际数据,,包括每个像素的颜色分量和透明度值,通常以字节(Byte)的形式存储。

是图像的实际像素内容,用于渲染和处理,开发者可以直接访问并修改缓冲区内容,实现像素级操作。

if let cgImage = UIImage(named: "example")?.cgImage,
   let dataProvider = cgImage.dataProvider,
   let pixelData = dataProvider.data {
    let buffer = CFDataGetBytePtr(pixelData)
    let bytesPerRow = cgImage.bytesPerRow
    print("Pixel data size: \(CFDataGetLength(pixelData))")
    print("Bytes per row: \(bytesPerRow)")
}

如何创建和使用 CGImage

1、从 UIImage 获取 CGImage

UIImage 可以轻松转换为 CGImage:

if let cgImage = UIImage(named: "example")?.cgImage {
    // 使用 cgImage
    print("CGImage width: \(cgImage.width), height: \(cgImage.height)")
}

2、创建 CGImage

使用 CGDataProvider 和其他参数手动创建 CGImage:

import CoreGraphics

let width = 100
let height = 100
let bitsPerComponent = 8
let bytesPerRow = width * 4
let colorSpace = CGColorSpaceCreateDeviceRGB()

// 创建空像素数据
let bitmapData = malloc(height * bytesPerRow)
defer { free(bitmapData) }

if let dataProvider = CGDataProvider(dataInfo: nil, data: bitmapData!, size: height * bytesPerRow, releaseData: { _, data, _ in
    free(data)
}) {
    let cgImage = CGImage(
        width: width,
        height: height,
        bitsPerComponent: bitsPerComponent,
        bitsPerPixel: bitsPerComponent * 4,
        bytesPerRow: bytesPerRow,
        space: colorSpace,
        bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue),
        provider: dataProvider,
        decode: nil,
        shouldInterpolate: true,
        intent: .defaultIntent
    )
    
    print("Created CGImage: \(String(describing: cgImage))")
}

3、将 CGImage 转为 UIImage

从 CGImage 创建 UIImage:

if let cgImage = UIImage(named: "example")?.cgImage {
    let uiImage = UIImage(cgImage: cgImage)
    print("UIImage created from CGImage")
}

4、绘制 CGImage

使用 CGContext 将 CGImage 绘制到屏幕或图形上下文中:

if let cgImage = UIImage(named: "example")?.cgImage {
    let context = UIGraphicsGetCurrentContext()
    context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: 200, height: 200))
}

CGImage 的常见用途

1、图像处理

与 Core Graphics 或 Core Image 结合,用于精确的像素级图像操作。

2、图像渲染

在自定义绘图代码中,使用 CGContext 渲染图像。

3、高性能需求

比较底层,适合高性能图像处理场景。

4、与 Core Animation 和 Core Image 集成

可与 CAAnimation、CIFilter 等结合,进行高级图像效果处理。

UIImage 与 CGImage 的比较

1、所属框架:UIImage属于UIKit,CGImage属于Core Graphics;

2、操作级别:UIImage属于高级抽象(易用性高),CGImage低级别(更灵活);

3、可变性:UIImage可通过方法间接修改,CGImage不可变;

4、用途:UIImage显示和管理图像,CGImage精细控制图像数据;

5、性能:UIImage较高层,性能可能稍低,CGImage更底层,适合高性能场景;

总结

CGImage 是 Core Graphics 提供的低级位图图像类型,适合需要精细像素操作的场景。

UIImage 是 UIKit 的高层抽象,封装了 CGImage,主要用于 iOS 界面开发中显示图像。

在 SwiftUI 中,Image(uiImage:) 可以桥接 UIImage 和 SwiftUI 的 Image,从而间接使用 CGImage。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注