32位大端点浮点数据到CGImage

时间:2011-12-06 00:39:42

标签: objective-c cocoa floating-point cgimage nsimagerep

我正在尝试编写一个读取FITS图像的应用程序。 FITS代表柔性图像传输格式,它是一种格式,主要用于存储与天体物理相关的科学数据,其次,它被大多数使用CCD相机拍摄天空照片的amator天文学家使用。所以FITS文件包含图像,但它们也可能包含表格和其他类型的数据。因为我是Objectiv-C和可可编程的新手(一年前我开始这个项目,但是因为我很忙,我几乎没有触摸它一年!),我开始尝试创建一个允许我转换它的库将文件的图像内容发送到NSImageRep。 FITS图像二进制数据可以是8位/像素,16位/像素,32位/像素无符号整数或32位/像素,64位/像素浮点,全部采用Big endian。

我设法用16位/像素,32位/像素无符号整数的灰度FITS图像进行图像表示,但是当我寻找32位/像素浮点时我得到了非常奇怪的行为(这个问题值得RGB 32位/像素浮点)。到目前为止,我还没有测试基于16位/像素和32位/像素整数数据的8位/像素整数数据和RGB图像,因为我还没有在网上找到示例文件。

以下是我的代码,用于创建灰度图像形式适合文件:

-(void) ConstructImgGreyScale
{
CGBitmapInfo     bitmapInfo;
int bytesPerRow;

switch ([self BITPIX])   // BITPIX : Number bits/pixel. Information extracted from the FITS header
{
    case 8:
        bytesPerRow=sizeof(int8_t);
        bitmapInfo = kCGImageAlphaNone ;
        break;
    case 16:
        bytesPerRow=sizeof(int16_t);
        bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder16Big;
        break;
    case 32:
        bytesPerRow=sizeof(int32_t);
        bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder32Big;
        break;
    case 64:
        bytesPerRow=sizeof(int64_t);
        bitmapInfo = kCGImageAlphaNone;
        break;
    case -32:
        bytesPerRow=sizeof(Float32);
        bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrder32Big  | kCGBitmapFloatComponents;
    case -64:
        bytesPerRow=sizeof(Float64);
        bitmapInfo = kCGImageAlphaNone  | kCGBitmapFloatComponents;
        break;
    default:
        NSLog(@"Unknown pixel bit size");
        return;
}
[self setBitsPerSample:abs([self BITPIX])];

[self setColorSpaceName:NSCalibratedWhiteColorSpace];

[self setPixelsWide:[self NAXESofAxis:0]]; // <- Size of the X axis. Extracted from FITS header
[self setPixelsHigh:[self NAXESofAxis:1]]; // <- Size of the Y axis. Extracted from FITS header

[self setSize:  NSMakeSize( 2*[self pixelsWide], 2*[self pixelsHigh])];

[self setAlpha: NO];
[self setOpaque:NO];

CGDataProviderRef provider=CGDataProviderCreateWithCFData ((CFDataRef) Img);

CGFloat Scale[2]={0,28};
image = CGImageCreate ([self pixelsWide],
                       [self pixelsHigh],
                       [self bitsPerSample],
                       [self bitsPerSample],
                       [self pixelsWide]*bytesPerRow,
                       [[NSColorSpace deviceGrayColorSpace] CGColorSpace],
                       bitmapInfo,
                       provider,
                       NULL,
                       NO,
                       kCGRenderingIntentDefault
                       );

CGDataProviderRelease(provider);
return;
}  

以下是32位/像素浮点数据的结果快照:NASA HST picture

图像似乎向左移动,但更令人讨厌的是我在同一帧中获得了同一图像(帧的上部和下部)的两个表示。

对于其他一些文件,行为更奇怪: Star Field 1,(对于另一个链接,评论,作为新用户,我在这个文本中不能有两个以上的链接。以及我不能直接放置图像。)

所有三个星级场图像都是相同拟合文件内容的表示。我在帧的底部获得了正确的图像表示(星星太饱和但我还没有使用编码)。但是,在上半部分,每次打开相同的文件时,我都会得到不同的图像表示。看起来每次打开这个文件时,都不会使用相同的字节序列来生成图像表示(至少在上部)。

另外,我不知道底部复制的图像是否包含一半的数据 而上半部分是另一半,或者它只是数据的副本。

当我以原始格式(人类可读数字)转换我的数据内容时,该数字与像素中的数据兼容,处于良好位置。这让我觉得问题不是来自数据,而是来自CGImage解释数据的方式,即我在传递给CGImageCreate函数的参数中的某个地方错了。

在RGB适合图像数据的情况下,我在最后获得18个图像到我的帧中。每个R,G和B图像的6份副本。全部为灰度。请注意,在RGB图像的情况下,我的代码是不同的。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

好的,我终于找到了关于我的问题的解决方案,关于图像的重复。这是一个非常愚蠢的错误,我并不为自己没有早点找到它而自豪。

在代码中,我忘记了break中的case -32。关于图片的转变仍然存在问题。我打开32位整数图像时看不到移位,但它出现在32位浮点数据上。

是否有人知道我的代码中可能出现这种转变的位置?这是由于我构建图像的方式吗?或者它可能是我绘制图像的方式吗?

Bellow是我用来绘制图像的代码。由于图像是第一次倒置,我对坐标做了一点改动。

- (bool)draw {
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
if (!context || !image) {
    return NO;
}
NSSize size = [self size];

CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1, -1);

CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), image);
return YES;
}