- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的程序中有一个大型一维动态数组,它表示磁盘上的 FITS 图像,即它保存图像的所有像素值。数组的类型是double。目前,我只关心单色图像。
由于 Cocoa 不直接支持 FITS 格式,因此我使用 CFITSIO 库读取图像。这是可行的 - 我可以根据需要操作数组并使用库将结果保存到磁盘。
但是,我现在想要显示图像。我认为这是 NSImage 或 NSView 可以做的事情。但类引用似乎没有列出可以采用 C 数组并最终返回 NSImage 对象的方法。我发现的最接近的是-initWithData:(NSData*)。但我不能 100% 确定这是否是我所需要的。
我是不是找错树了?任何指向可以处理此问题的类或方法的指针都将是
编辑:
这是更新后的代码。请注意,我将每个像素设置为 0xFFFF。这只会产生灰色图像。这当然只是一个测试。加载实际的 FITS 文件时,我将 0xFFFF 替换为 imageArray[i * width + j]
。这在 8 位中完美运行(当然,我将每个像素值除以 256 以用 8 位表示)。
NSBitmapImageRep *greyRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:width
pixelsHigh:height
bitsPerSample:16
samplesPerPixel:1
hasAlpha:NO
isPlanar:NO
colorSpaceName:NSCalibratedWhiteColorSpace
bytesPerRow:0
bitsPerPixel:16];
NSInteger rowBytes = [greyRep bytesPerRow];
unsigned short*pix = (unsigned short*)[greyRep bitmapData];
NSLog(@"Row Bytes: %d",rowBytes);
if(temp.bitPix == 16) // 16 bit image
{
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
pix[i * rowBytes + j] = 0xFFFF;
}
}
}
我也尝试过直接使用Quartz2D。即使是 16 位,这也确实会产生正确的图像。但奇怪的是,数据数组将 0xFF 作为白色,而不是 0xFFFF。所以我仍然必须将所有内容除以 0xFF - 在此过程中丢失数据。 Quartz2D代码:
short* grey = (short*)malloc(width*height*sizeof(short));
for(int i=0;i<width*height; i++)
{
grey[i] = imageArray[i];
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapContext = CGBitmapContextCreate(grey, width, height, 16, width*2, colorSpace, kCGImageAlphaNone);
CFRelease(colorSpace);
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
NSImage *greyImage = [[NSImage alloc] initWithCGImage:cgImage size:NSMakeSize(width, height)];
有什么建议吗?
最佳答案
initWithData
仅适用于系统已知的图像类型。对于未知类型和原始像素数据,您需要自己构建图像表示。您可以按照 Kirby 链接到的答案中的建议通过 Core Graphics 执行此操作。或者,您可以通过创建并添加 NSBitmapImageRep
来使用 NSImage
。
确切的细节取决于像素数据的格式,但以下是灰度图像的处理示例,其中源数据(samples
数组)在范围内表示为 double [0,1]:
/* generate a greyscale image representation */
NSBitmapImageRep *greyRep =
[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil // allocate the pixel buffer for us
pixelsWide: xDim
pixelsHigh: yDim
bitsPerSample: 8
samplesPerPixel: 1
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedWhiteColorSpace // 0 = black, 1 = white in this color space
bytesPerRow: 0 // passing 0 means "you figure it out"
bitsPerPixel: 8]; // this must agree with bitsPerSample and samplesPerPixel
NSInteger rowBytes = [greyRep bytesPerRow];
unsigned char* pix = [greyRep bitmapData];
for ( i = 0; i < yDim; ++i )
{
for ( j = 0; j < xDim; ++j )
{
pix[i * rowBytes + j] = (unsigned char)(255 * (samples[i * xDim + j]));
}
}
NSImage* greyscale = [[NSImage alloc] initWithSize:NSMakeSize(xDim,yDim)];
[greyscale addRepresentation:greyRep];
[greyRep release];
<小时/>
编辑(回应评论)
我不确定是否支持 16 位样本,但您似乎已经确认它们是支持的。
您所看到的源于仍然将像素视为 unsigned char
,即 8 位。因此,您只需设置每行的一半,并且一次一个字节地将每个像素设置为两个字节值 0xFF00
- 不完全是真正的白色,但非常接近。图像的另一半没有被触摸,但会被初始化为 0,因此它保持黑色。
您需要在 16 位中工作,首先转换从代表返回的值:
unsigned short * pix = (unsigned short*) [greyRep bitmapData];
然后将 16 位值分配给像素:
if ( j % 2 )
{
pix[i * rowBytes + j] = 0xFFFF;
}
else
{
pix[i * rowBytes + j] = 0;
}
从头开始,rowBytes
以字节为单位,因此我们需要坚持使用 unsigned char
来表示 pix
并在分配时进行强制转换,这有点更丑:
if ( j % 2 )
{
*((unsigned short*) (pix + i * rowBytes + j * 2)) = 0xFFFF;
}
else
{
*((unsigned short*) (pix + i * rowBytes + j * 2)) = 0;
}
(我已经改变了子句的顺序,因为 == 0
似乎是多余的。实际上,对于这样的事情,使用 ?:
语法会更简洁,但 C 语言已经够多了。)
关于cocoa - 来自一维像素阵列的 NSImage?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5458770/
我有一个矩形 NSImage A,我想缩放以嵌入到方形透明图像 B 中,保持 A 的比例。所以,最后我会得到一个带有矩形的方形图像。 我该如何构图?我的意思是,如何在另一个 NSImage 上绘制一个
我有一堆 NSImages,我将它们保存在 PDFDocument 中,作为 PDFPages。当我第一次插入 NSImage 时,NSImage 的大小以点 (72 dpi) 为单位,而(仅)NSI
我试图理解为什么 var tmp: Any = NSImage(byReferencingFile: somePath) var img: NSImage = tmp as NSImage 不会工作并
好吧,我很困惑,因为这应该很简单。 在 Xcode 5 中,我开始了一个新的 iphone 项目。在 ViewDidLoad 中,我开始输入: NSImage *图像 ... 实际上在“NSI”点……
我正在尝试将文件从 xcassets 加载到 NSImage,其中 Assets 名称是 Logo 。 我试过这个: let logoIcon = NSImage(named: "logo") 但我一
我正在编写一个简单的 MacRuby 应用程序。我有一个 NSView,它在调用 drawRect() 时在自身内部绘制图像。 在那个 NSView 子类中,我的 drawRect() 有(以及其他一
所以我有一个 NSImage *startingImage 它由带有灰色色彩空间的 NSBitmapImageRep 表示 我需要反转它的颜色,因此我将其转换为 CIImage CIImage *
首先,我知道我不应该使用 SQLite 数据库来存储图像,但我只存储非常小的网站图标。 我的问题是我尝试将这些图标插入数据库(似乎有效),我将图标转换为 NSData与 -tiffrepresenta
我正在尝试制作一个简单的基于文档的 cocoa 应用程序,可以在 pdf 文件中保存和加载图像。 对于保存部分,我正在使用 - (NSData *)dataOfType:(NSString *)typ
我使用 NSAffineTransform 类在其中心旋转了 NSImage,它可以工作。代码在这里: - (NSImage*)rotateImage: (NSImage*)myImage angle
我是 cocoa 和编程的新手,如果这是基本的东西,我很抱歉。 我正在使用 ARC。我有一个 NSImageView 组件,它由 DropZone 类控制。我将图像拖放到其中,但是一旦我尝试调用我得到
我想创建 NSScrollView 对象的 NSImage,这样我就可以将平面图形用于动画目的。 当我将 ScrollView 对象渲染为图形并将其添加回我的窗口时,它可以工作,但看起来非常糟糕,就像
到目前为止,我已经构建了一个应用程序,允许用户将图像拖放到 NSImageView 上。但是,我希望能够通过简单地单击任何图像并按住鼠标按钮来移动其位置来移动这些图像。 设置图像后如何操作 NSIma
我正在尝试打印 NSImage,但无法将其调整为正确的尺寸。我希望 NSImage 在任何足够大的纸张上打印为 4"x6"照片。这是我现在的代码。 var printView = NSImageVie
这可能是一个新问题,但我无法理解如何操作 NSImage 实例。 我正在尝试创建一个方法,该方法将采用 NSImage (一个图标),在其上绘制另一个 NSImage (复选标记),然后返回修改后的
由于 Cocoa-Java 已弃用,我正在将 Cocoa-Java 代码迁移到 Cocoa + JNI。该代码打印存储在文件中的图像。新的 Cocoa 代码基本上是: NSImage *image =
我正在尝试设置一个自定义拖动图标以在 NSTableView 中使用。一切似乎都正常,但由于我对 Quartz 缺乏经验,我遇到了问题。 - (NSImage *)dragImageForRowsWi
我有许多 NSImage,正在自定义 NSView 子类中渲染。当用户将鼠标放在这些图像上时,我希望放大这些图像,并且想知道执行此操作的最佳方法。 目前我正在使用 NSView 的 drawRect:
我的程序中有一个大型一维动态数组,它表示磁盘上的 FITS 图像,即它保存图像的所有像素值。数组的类型是double。目前,我只关心单色图像。 由于 Cocoa 不直接支持 FITS 格式,因此我使用
我想获取 NSImage.h 中定义的常量的图像文件,例如 NSImageNameGoRightTemplate 。我想复制并编辑其中一些。有谁知道这些图像位于哪里?我太笨了,在驱动器上找不到它们..
我是一名优秀的程序员,十分优秀!