我找到了两种从CGImageRef获取原始数据的方法:
第一种方法:
unsigned char *CGImageCopyRawData(CGImageRef image, size_t *rawDataLength) {
CGDataProviderRef dataProvider = CGImageGetDataProvider(image);
CFDataRef data = CGDataProviderCopyData(dataProvider);
if(rawDataLength) *rawDataLength = (size_t) CFDataGetLength(data);
CFRelease(dataProvider);
CFRelease(data);
return CFDataGetBytePtr(data);
}
第二种方法:
static unsigned char *CGImageCopyPixelData(CGImageRef image, CGColorSpaceRef colorSpace, uint32_t bitmap_info, size_t *pixelDataLength) {
unsigned char *pixelData = 0;
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
// allocate image pixel components array, where each component takes one byte (unsigned char)
size_t dataLength = width*height*COMPONENTS_PER_PIXEL*BYTES_PER_COMPONENT;
pixelData = (unsigned char*) malloc(sizeof(unsigned char) * (dataLength));
if(pixelData == 0) {
*pixelDataLength = 0;
return 0;
}
// draw image using core graphics context in frame buffer
CGContextRef context = CGBitmapContextCreate(pixelData, width, height, BITS_PER_COMPONENT,
COMPONENTS_PER_PIXEL * width, colorSpace, bitmap_info);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), image);
CGContextRelease(context);
if(pixelDataLength) *pixelDataLength = dataLength;
return pixelData;
}
我听说第一种方法返回原始数据,而不保证色彩空间,每个像素的组件数,每个组件的位数,字节顺序Big-endian,Little-endian。
但考虑到 CGImageRef 只是来自CGDisplayCreateImage(mainDisplayId)
的屏幕截图,我可以假设这将是bitmapMask kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
。
但是这种方法会返回不同的结果,并且它不是不同的字节顺序,但是在Adobe Photoshop等图形程序中检查十六进制颜色时,颜色略有不同但颜色相似:
第一个输出是:
[F8 E0 D2 FF] [F8 E0 D2 FF] [F8 E0 D2 FF] [F8 E0 D2 FF] [F8 E1 D2 FF] [F8 E1 D2 FF] [F8 E1 D2 FF] [F8 E1 D2 FF] [F8 E1 D2 FF] [F8 E1 D2 FF] [F8 E1 D2 FF]...
第二个输出是:
[F7 E1 D4 FF] [F7 E1 D4 FF] [F7 E1 D4 FF] [F7 E1 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF] [F7 E2 D4 FF]...
所以当你看到只有一点点设置或没有设置时,可能是C中有符号/无符号字符的东西?