gpt4 book ai didi

objective-c - 32 位大端 float 据到 CGImage

转载 作者:搜寻专家 更新时间:2023-10-30 20:26:26 25 4
gpt4 key购买 nike

我正在尝试编写一个读取 FITS 图像的应用程序。 FITS 代表 Flexible Image Transport 格式,这种格式主要用于存储与天体物理学相关的科学数据,其次,它被大多数使用 CCD 相机拍摄天空的爱好者天文学家使用。所以 FITS 文件包含图像,但它们也可能包含表格和其他类型的数据。由于我是 Objectiv-C 和 cocoa 编程的新手(我一年前开始这个项目,但由于我很忙,我几乎一年没碰它!),我开始尝试创建一个库,它允许我转换文件的图像内容到 NSImageRep。 FITS 图像二进制数据可以是 8 位/像素、16 位/像素、32 位/像素无符号整数或 32 位/像素、64 位/像素 float ,均采用大端格式。

我设法用 16 位/像素、32 位/像素无符号整数表示灰度 FITS 图像,但是当我寻找 32 位/像素浮点时,我得到了非常奇怪的行为(这个问题值得RGB 32 位/像素 float )。到目前为止,我还没有测试基于 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/bits/pix float 据的结果快照:NASA HST picture !

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

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

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

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

当我以原始格式(人类可读的数字)转换我的数据内容时,数字与像素中应有的内容兼容,位于正确的位置。这让我认为问题不是来自数据,而是来自 CGImage 解释数据的方式,即我在传递给 CGImageCreate 函数的参数中的某处是错误的。

在 RGB 适合图像数据的情况下,我在最后将 18 个图像放入我的帧中。 R、G 和 B 图像各 6 份。全部为灰度。请注意,对于 RGB 图像,我的代码是不同的。

我做错了什么?

最佳答案

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

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

有没有人知道我的代码中这种转变可能来自何处?是因为我构建图像的方式吗?或者这可能是我绘制图像的方式造成的?

下面是我用来绘制图像的一段代码。由于图像首先是颠倒的,所以我稍微改变了坐标。

- (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;
}

关于objective-c - 32 位大端 float 据到 CGImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8393918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com