如何从头开始创建NSBitmapImageRep?

如何从头开始创建NSBitmapImageRep?,image,cocoa,nsbezierpath,nsbitmapimagerep,Image,Cocoa,Nsbezierpath,Nsbitmapimagerep,首先:我想使用NSBezierPath在我的应用程序中绘制一些简单的按钮插图,因此我想我应该创建一个NSBitmapImageRep,获取cImage,从中创建一个NSImage,然后在按钮上调用setImage:。如果我错了,请纠正我 所以我去看了如何创建一个NSBitmapImage,发现: **initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmap

首先:我想使用
NSBezierPath
在我的应用程序中绘制一些简单的按钮插图,因此我想我应该创建一个
NSBitmapImageRep
,获取
cImage
,从中创建一个
NSImage
,然后在按钮上调用setImage:。如果我错了,请纠正我

所以我去看了如何创建一个
NSBitmapImage
,发现:
**initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:*

请记住,我要寻找的是一个类似于
initWithSize:
的东西,我应该为这些值输入什么?

很好地解释了这一点

planes
参数有点混乱。它基本上是一个指向像素的指针。因此,如果数组中的像素由一个名为“pixels”的变量指向,如下所示:

unsigned char* pixels = malloc (width * height * 4); // assumes ARGB 8-bit pixels
NSBitmapImageRep* myImageRep = [[NSBitmapImageRep alloc] initWithDataPlanes:&pixels
... etc...];
其余参数非常简单
pixelWidth
pixelHeight
正是您所期望的。其他值都对应于数据的排列方式。您是否使用每个通道8位的ARGB数据?还是每个通道32位的RGBA

nsDeviceGBColorSpace
可能足以满足您对颜色空间的使用


如果您传入一个指向图像数据的指针,
isPlanar
通道应该是
NO

任何特定原因都不是简单地创建一个新的
NSImage
并通过使用焦点锁定将绘图代码括在括号内进行绘图

NSImage* anImage = [[NSImage alloc] initWithSize:NSMakeSize(100.0,  100.0)];
[anImage lockFocus];

// Do your drawing here...

[anImage unlockFocus];

(顺便说一句,这是您的朋友)

您不需要为数据平面分配空间。下面是使用alpha组件创建空32位
NSBitmapImageRep
的调用

NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                                   pixelsWide:pixelsWide
                                                                   pixelsHigh:pixelsHigh
                                                                bitsPerSample:8
                                                              samplesPerPixel:4
                                                                     hasAlpha:YES
                                                                     isPlanar:NO
                                                               colorSpaceName:NSDeviceRGBColorSpace
                                                                   bytesPerRow:4 * pixelsWide
                                                                  bitsPerPixel:32];

我应该提到的是,我发现自己挠头的部分原因是我对位图图像术语的了解有点…点菜。例如,文档告诉我,对于bps参数,“所有组件……每个样本都有相同的位。bps应该是以下值之一:1、2、4、8、12或16。”但我不确定为每个样本提供更多位的好处是什么。这是可以理解的。(他们也忽略了32是一个有效值。)在大多数情况下,你的眼睛无法检测到8以上的任何东西。但是,如果要对结果进行多次图像处理,那么额外的位(如果超过8)可能很有用。在您的例子中,正如您所描述的,8可能很好。您实际上不必分配这些像素,而是为数据平面传递NULL。我发布了一个答案,其中包含了您想要的标准空
NSBitmapImageRep
足够公平的所有适当参数。在我的使用中,我倾向于首先分配缓冲区,使用其他方法将一些数据放入缓冲区,例如从缓冲区中创建CGBitmapContext,或者其他任何方法,然后将其转换为NSBitmapImageRep。我还需要跟踪缓冲区,以便手动控制其生存期。但是你是对的,你不需要那样做。我不知道你可以那样做。我已经略读了《可可绘图指南》,但一定是错过了。@popcellen不客气。是的,仅仅创建一个没有任何特定约束的图像是非常简单的