带有CGImageCreate的32位/分量图像实际上只有8位/分量

时间:2011-03-31 01:56:38

标签: objective-c cocoa core-graphics quartz-graphics

在过去的4到5个小时里,我一直在努力解决这个非常奇怪的问题。我有一个字节数组,其中包含我想要制作图像的像素值。该数组表示每个组件值32位。没有Alpha通道,因此图像为96位/像素。

我已将所有这些内容指定给CGImageCreate函数,如下所示:

  CGImageRef img = CGImageCreate(width, height, 32, 96, bytesPerRow, space, kCGImageAlphaNone , provider, NULL, NO, kCGRenderingIntentDefault);

bytesPerRow是3*width*4。这是因为每个像素有3个组件,每个组件需要4个字节(32位)。因此,每行的总字节数为3 * 4 *宽度。数据提供者定义如下:

     CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,bitmapData,3*4*width*height,NULL);

这就是事情变得怪异的地方。在我的数组中,我明确地将值设置为0x000000FF(对于所有3个通道)然而,图像将显示为完全白色。如果我将值设置为0xFFFFFF00,则图像变为黑色。这告诉我,由于某种原因,程序不会读取每个组件的所有4个字节,而是读取最低有效字节。我尝试了各种组合 - 甚至包括Alpha通道,但它对此没有任何影响。

该计划对此无视:0xAAAAAA00。它只是将其读为0.当我明确指出每个组件的位数是32位时,该函数是否应该考虑到这一点并且实际上从数组中读取4个字节?

bytes数组定义为:bitmapData = (char*)malloc(bytesPerRow*height);我正在为数组赋值如下

 for(i=0;i<width*height;i++)
{
    *((unsigned int *)(bitmapData + 12*i + 0)) = 0xFFFFFF00;
    *((unsigned int *)(bitmapData + 12*i + 4)) = 0xFFFFFF00;
    *((unsigned int *)(bitmapData + 12*i + 8)) = 0xFFFFFF00;
}

请注意,我将数组作为int来处理,以处理4个字节的内存。我乘以12是因为每个像素有12个字节。添加4和8允许循环寻址绿色和蓝色通道。请注意,我已经在调试器中检查了数组的内存,这似乎完全没问题。循环写入4个字节。任何类型的指针都会对你有所帮助。我的最终目标是能够读取32位FITS文件 - 我已经编写了程序。我只使用上面的数组测试上面的代码。

如果重要的话,这里是完整的代码。这是我自定义视图的drawRect:(NSRect)dirtyRect方法:

int width, height, bytesPerRow;
int i;

width = 256;
height = 256;
bytesPerRow = 3*width*4;

char *bitmapData;
bitmapData = (char*)malloc(bytesPerRow*height);
for(i=0;i<width*height;i++)
{
    *((unsigned int *)(bitmapData + 12*i + 0)) = 0xFFFFFF00;
    *((unsigned int *)(bitmapData + 12*i + 4)) = 0xFFFFFF00;
    *((unsigned int *)(bitmapData + 12*i + 8)) = 0xFFFFFF00;
}
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,bitmapData,3*4*width*height,NULL);
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();

CGImageRef img = CGImageCreate(width, height, 32, 96, bytesPerRow, space, kCGImageAlphaNone, provider, NULL, NO, kCGRenderingIntentDefault);

CGColorSpaceRelease(space);
CGDataProviderRelease(provider);

CGContextRef theContext = [[NSGraphicsContext currentContext] graphicsPort];
CGContextDrawImage(theContext, CGRectMake(0,0,width,height), img);

1 个答案:

答案 0 :(得分:2)

我看到一些值得指出的事情:

首先,Quartz 2D编程指南doesn't list 96-bpp RGB作为支持的格式。您可以尝试128-bpp RGB。

其次,你正在研究一个小端系统*,这意味着LSB首先出现。将您设置每个组件的值更改为0x33000000EE,您将看到浅灰色(EE),而不是深灰色(33)。

最重要的是,当bbum指出你的显示器不能 渲染那种颜色范围**时,bbum是绝对正确的。它被压缩到8-bpc只是为了展示。如果它在内存中是正确的,那么它在内存中是正确的。


*:更多的是遗憾。 R.I.P PPC。

**:也许NASA有一个可以吗?