Swift中如何创建Core Graphics位图上下文逐像素绘制10x10 RGB图像
Core Graphics 逐像素生成10x10自定义RGB图像的实现方法
核心逻辑
很多人找不到直接往Core Graphics位图上下文写数据的方法,本质是误解了上下文的存储机制:CGBitmapContext创建时传入的像素缓冲区,就是上下文本身的像素存储,上下文不会额外分配独立内存,只要上下文没被释放,你可以直接操作这块内存修改任意像素值,不需要额外的“写入”API。
分步实现流程
- 定义基础参数
对于10x10尺寸、8位每通道的RGB图像,采用性能最优的BGRA内存排列(带预乘Alpha),每个像素占4字节:- 图像宽度/高度:固定为10
- 每行字节数:
10 * 4 = 40 - 总内存大小:
10 * 10 *4 = 400字节
- 准备像素缓冲区
用calloc分配对应大小的内存块,自动初始化为零值,避免随机内存垃圾导致的画面异常。 - 合规创建位图上下文
调用CGBitmapContextCreate时传入匹配参数,避免出现颜色偏移、内存错位问题:- 传入像素缓冲区指针、图像宽高
- 每个颜色分量的位数:8
- 每行字节数:预先计算的40
- 颜色空间:
CGColorSpaceCreateDeviceRGB(),匹配设备的实际RGB显示范围,避免用通用颜色空间导致的色彩偏差 - 位图配置:
kCGImageAlphaPremultipliedFirst,对应BGRA的内存排列顺序,是Apple官方推荐的最优性能配置
- 逐像素写入颜色值
对任意坐标为(x,y)的像素,计算它在缓冲区中的内存偏移:偏移量 = y * 每行字节数 + x * 4,按B、G、R、A的顺序在对应偏移位置写入0-255的通道值即可。注意预乘Alpha规则:当Alpha值小于255时,RGB通道的实际值要提前乘以Alpha占比,避免颜色溢出。 - 生成最终可用图像
所有像素值写入完成后,调用CGBitmapContextCreateImage从上下文导出CGImage对象,即可包装为UIImage使用。 - 内存释放
操作完成后必须依次释放生成的CGImage、位图上下文、颜色空间、最初分配的像素缓冲区,避免内存泄漏。
参考实现代码
// 基础参数配置 const size_t imageWidth = 10; const size_t imageHeight = 10; const size_t bytesPerPixel = 4; const size_t bytesPerRow = imageWidth * bytesPerPixel; const size_t totalBufferSize = bytesPerRow * imageHeight; // 分配并清零像素缓冲区 UInt8 *pixelBuffer = calloc(1, totalBufferSize); // 创建设备RGB颜色空间 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // 创建位图上下文 CGContextRef bitmapContext = CGBitmapContextCreate( pixelBuffer, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst ); // 逐像素写入自定义RGB值 for (size_t y = 0; y < imageHeight; y++) { for (size_t x = 0; x < imageWidth; x++) { size_t pixelOffset = y * bytesPerRow + x * bytesPerPixel; // 内存顺序对应BGRA排列 pixelBuffer[pixelOffset] = (UInt8)(x * 25); // 蓝色通道 pixelBuffer[pixelOffset+1] = (UInt8)(y * 25); // 绿色通道 pixelBuffer[pixelOffset+2] = (UInt8)(255 - x*25);// 红色通道 pixelBuffer[pixelOffset+3] = 255; // Alpha通道(完全不透明) } } // 导出最终图像 CGImageRef outputImage = CGBitmapContextCreateImage(bitmapContext); UIImage *result = [UIImage imageWithCGImage:outputImage]; // 清理所有资源 CGImageRelease(outputImage); CGContextRelease(bitmapContext); CGColorSpaceRelease(colorSpace); free(pixelBuffer);
内容的提问来源于stack exchange,提问作者Benj
相关产品推荐
相关产品推荐

