我正在考虑优化从CGImage获取像素数据的例程。目前这种方式(非常低效)的方法是创建一个新的CGContext,将CGImage绘制到上下文中,然后从上下文中获取数据。
我有以下优化程序来处理这个问题:
CGImageRef imageRef = image.CGImage;
uint8_t *pixelData = NULL;
CGDataProviderRef imageDataProvider = CGImageGetDataProvider(imageRef);
CFDataRef imageData = CGDataProviderCopyData(imageDataProvider);
pixelData = (uint8_t *)malloc(CFDataGetLength(imageData));
CFDataGetBytes(imageData, CFRangeMake(0, CFDataGetLength(imageData)), pixelData);
CFRelease(imageData);
这几乎可行。在查看和比较通过两种方法获得的像素数据的十六进制转储之后,我发现在上述情况下,每6360字节有8个字节的0。否则,数据是相同的。例如
这是与未优化版本的比较:
在0的8个字节之后,正确的像素数据继续。任何人都知道为什么会这样吗?
更新: 这是我正在优化的例程(剪切代码只是获取大小信息,以及其他非重要的东西;相关位是返回的像素数据):
CGContextRef context = NULL;
CGImageRef imageRef = image.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst;
// ... SNIP ...
context = CGBitmapContextCreate(...);
CGColorSpaceRelease(colorSpace);
// ... SNIP ...
CGContextDrawImage(context, rect, imageRef);
uint8_t *pixelData = (uint8_t *)CGBitmapContextGetData(context);
CGContextRelease(context);
显然,这只是获取基础像素数据的大量工作。创建一个上下文,然后绘制它。第一个例程的速度是5到10倍。但正如我所指出的,两个例程返回的像素数据几乎完全相同,只是在优化代码中每6360字节插入8个零字节值(在图像中突出显示)。
否则,其他一切都是相同的 - 颜色值,字节顺序等。
答案 0 :(得分:4)
位图数据在每行像素的末尾都有填充,以将每行的字节数舍入为更大的值。 (在这种情况下,16个字节的倍数。)
添加此填充以使处理和绘制图像更快。
您应该使用CGImageGetBytesPerRow()
来查找每行占用的字节数。不要认为它与CGImageGetWidth() * CGImageGetBitsPerPixel() / 8
相同;每行的字节数可能更大。
请注意,任意CGImage
背后的数据可能不是您期望的格式。您不能假设所有图像都是32位/像素ARGB,没有填充。您应该使用CG函数来确定数据的格式,或者将图像重新绘制为具有您期望的确切格式的位图上下文。后者通常要容易得多 - 让CG为你做转换。
(你没有显示你传递给CGBitmapContextCreate
的参数。你在计算一个确切的bytesPerRow
还是你传入0?如果你传入0,CG可能会添加填充你,你可能会发现在上下文中绘图更快。)