我正在尝试编写一个读取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图像的情况下,我的代码是不同的。
我做错了什么?
答案 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;
}