我用以下代码创建了32位NSImage。
NSBitmapImageRep *sourceRep = [[NSBitmapImageRep alloc] initWithData: imageData];
// create a new bitmap representation scaled down
NSBitmapImageRep *newRep =
[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: NULL
pixelsWide: imageSize
pixelsHigh: imageSize
bitsPerSample: 8
samplesPerPixel: 4
hasAlpha: YES
isPlanar: NO
colorSpaceName: NSCalibratedRGBColorSpace
bytesPerRow: 0
bitsPerPixel: 0];
// save the graphics context, create a bitmap context and set it as current
[NSGraphicsContext saveGraphicsState] ;
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep: newRep];
[NSGraphicsContext setCurrentContext: context] ;
// draw the bitmap image representation in it and restore the context
[sourceRep drawInRect: NSMakeRect(0.0f, 0.0f, imageSize, imageSize)] ;
[NSGraphicsContext restoreGraphicsState] ;
// set the size of the new bitmap representation
[newRep setSize: NSMakeSize(imageSize,imageSize)] ;
NSDictionary *imageProps2 = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:1.0], kCGImageDestinationLossyCompressionQuality,
nil];
imageData = [newRep representationUsingType: NSPNGFileType properties: imageProps2];
NSImage *bitImage = [[NSImage alloc]initWithData:imageData];
现在我需要创建8位(256色),4位(16色),1位(黑白)NSBitmapImageRep
表示。我现在想做什么?
答案 0 :(得分:3)
不幸的是,Cocoa似乎不支持对调色板图像进行操作。
我一直trying that before,我的结论是PNG不可能。 NSGIFFileType
是一个硬编码的例外,图形上下文比位图表示even more limited(例如RGBA仅支持预乘alpha)。
要解决此问题,我convert NSBitmapImageRep
to raw RGBA bitmap,使用libimagequant to remap it to a palette然后libpng或lodepng撰写PNG文件。
答案 1 :(得分:2)
可悲的是,我相信你不能使用核心图形。图形上下文不支持任何位数。
文档的表格为supported pixel formats。
显然,Carbon已经(有?)支持它,正如这里所提到的那样,他们也哀叹Cocoa缺乏对它的支持:
事实证明,基本上Cocoa / Quartz不支持将图像下采样为8位颜色。它支持绘制它们,它支持上采样,但不支持其他方式。我想这是Apple的一个故意设计,它将索引图像作为标准图形数据类型 - 毕竟,32位颜色更简单,对吧?嗯,它是,但仍然有用于8位。那么该怎么办?一种可能性是使用Carbon,因为General / QuickDraw的General / GWorld确实支持下采样等。
答案 2 :(得分:0)
那么评论可能太长了......
看起来这似乎是不可能的...所有可可的绘图部分似乎都想要使用24位颜色空间...我能够制作一个8位NSBitmapImageRep
但它是灰度。
所以我想我们必须在这里找出为什么。如果您希望能够使用由某些类型的表示支持的NSImages,我认为这是不可能的。
如果你想天真地下采样(改为最接近任何像素的24/32位值),这是非常可能的;这将是给出8位图像的外观。
如果您希望能够以良好的抖动/索引颜色编写这些文件,那么我认为最好的选择是写入支持您想要的图像格式(例如写入256色GIF)。 / p>
如果您想出于某种原因自行进行下采样,那么手头有两个问题:
如果您不想使用索引颜色,只想将8位分解为3-3-2 RGB,这样稍微容易一些,但结果比索引颜色差得多。
4位有点诡计,因为我甚至不知道4位色彩的良好历史使用。
我使用索引颜色来显示我曾做过的一个小项目中的mandelbrot设置的转义时间......
我刚刚确认它不再起作用了(旧的固定渲染管道OpenGL)。
但基本上对于视图,您可以使用glPixelMapuiv
将索引颜色映射到字节值,然后使用glDrawPixels
显示字节缓冲区;
所以......我想如果你评论并说出你为什么要做你正在做的事情,我们可以提供帮助。