我正在尝试编写一个读取 FITS 图像的应用程序。FITS代表灵活图像传输格式,它是一种主要用于存储与天体物理学相关的科学数据的格式,其次,它被大多数使用CCD相机拍摄天空的天文爱好者使用。因此 FITS 文件包含图像,但它们也可能包含表格和其他类型的数据。由于我是 Objectiv-C 和 cocoa 编程的新手(我一年前开始这个项目,但由于我很忙,我几乎一年都没有碰它!),我开始尝试创建一个库,让我可以转换文件的图像内容到 NSImageRep。FITS 图像二进制数据可能是 8 位/像素、16 位/像素、32 位/像素无符号整数或 32 位/像素、64 位/像素浮点数,均采用大端序。
我设法在 16 位/像素、32 位/像素无符号整数中获得灰度 FITS 图像的图像表示,但是当我寻找 32 位/像素浮点时,我得到了非常奇怪的行为(并且这个问题对于 RGB 32 位是值得的/pix 浮点数)。到目前为止,我还没有测试 8 位/像素整数数据和基于 16 位/像素和 32 位/像素整数数据的 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/bits/pix 浮点数据的结果快照:NASA HST 图片!
图像似乎向左移动,但更烦人的是我在同一帧中得到了同一图像的两个表示(帧的上部和下部)。
而对于其他一些文件,行为更奇怪: Star Field 1,(对于其他链接请参阅评论,作为新用户,我在此文本中不能有两个以上的链接。我也不能直接放图片。)
所有三个星域图像都是相同拟合文件内容的表示。我在帧的底部获得了正确的图像表示(星星太饱和了,但我还没有使用编码)。但是,在上半部分,每次我打开同一个文件时,我都会得到不同的图像表示。看起来每次我打开这个文件时,它都不会使用相同的字节序列来生成图像表示(至少对于上部而言)。
另外,我不知道底部重复的图像是否包含数据的一半,而上面的图像包含另一半数据,或者它是否只是数据的副本。
当我以原始格式(人类可读数字)转换我的数据内容时,该数字与像素中应该在良好位置的内容兼容。这让我认为问题不是来自数据,而是来自 CGImage 解释数据的方式,即我在传递给 CGImageCreate 函数的参数中的某处是错误的。
在 RGB 适合图像数据的情况下,我在最后将 18 个图像获取到我的帧中。R、G 和 B 图像各 6 个副本。全部为灰度。请注意,对于 RGB 图像,我的代码是不同的。
我究竟做错了什么 ?