2010-01-26 39 views
3

我试图用白色而不是黑色绘制标准NSImage。罚款在目前获取到NSGraphicsContext黑色绘制的图像,下面的工作:绘制标准NSImage倒置(白色而不是黑色)

NSImage* image = [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; 
[image drawInRect:r fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 

我预计NSCompositeXOR这样的伎俩,但没有。我需要去复杂的[CIFilter filterWithName:@“CIColorInvert”]路径吗?我觉得我必须错过简单的东西。

Anders

回答

6

核心图像路线将是最可靠的。这其实不是很复杂,我已经在下面发布了一个示例。如果你知道没有图像会被翻转,那么你可以删除转换代码。要注意的主要问题是,从NSImageCIImage的转换可能在性能方面非常昂贵,因此您应该确保在可能的情况下缓存CIImage,并且不要在每次绘图操作期间重新创建它。

CIImage* ciImage = [[CIImage alloc] initWithData:[yourImage TIFFRepresentation]]; 
if ([yourImage isFlipped]) 
{ 
    CGRect cgRect = [ciImage extent]; 
    CGAffineTransform transform; 
    transform = CGAffineTransformMakeTranslation(0.0,cgRect.size.height); 
    transform = CGAffineTransformScale(transform, 1.0, -1.0); 
    ciImage = [ciImage imageByApplyingTransform:transform]; 
} 
CIFilter* filter = [CIFilter filterWithName:@"CIColorInvert"]; 
[filter setDefaults]; 
[filter setValue:ciImage forKey:@"inputImage"]; 
CIImage* output = [filter valueForKey:@"outputImage"]; 
[output drawAtPoint:NSZeroPoint fromRect:NSRectFromCGRect([output extent]) operation:NSCompositeSourceOver fraction:1.0]; 

注意:释放/保留内存管理留作练习,上面的代码假设垃圾回收。

如果你想以任意大小呈现图像,你可以做到以下几点:

NSSize imageSize = NSMakeSize(1024,768); //or whatever size you want 
[yourImage setSize:imageSize]; 
[yourImage lockFocus]; 
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, imageSize.width, imageSize.height)]; 
[yourImage unlockFocus]; 
CIImage* image = [CIImage imageWithData:[bitmap TIFFRepresentation]]; 
+0

谢谢,这的确解决了色彩反转问题。不幸的是,它并没有给我完整的分辨率:看起来最初的TIFFRepresentation比我想要绘制的尺寸小得多。我如何确保以高分辨率获取数据? – smartgo 2010-01-27 23:53:32

+0

你可以使用你想要的大小从NSImage创建一个'NSBitmapImageRep',然后从位图创建'CIImage',参见这里:http://pastie.org/798088 – 2010-01-28 01:31:19

+0

非常完美,非常感谢! – smartgo 2010-01-28 06:32:59

0

只要一注:我发现CIColorInvert过滤器并不总是可靠的。例如,如果您想要将Photoshop中反转的图像反转回来,CIFilter会生成更轻的图像。据我了解,这是因为CIFilter(gamma为1)和来自其他来源的图像的伽玛值不同而发生的。

当我正在寻找方法来更改CIFilter的伽玛值时,我发现一个提示CIContext中存在一个错误:将其伽玛值从默认值1更改将产生不可预知的结果。

无论如何,还有另一种解决方案来反转NSImage,它总能产生正确的结果 - 通过反转NSBitmapImageRep的像素。

我重新发布从etutorials.org(http://bit.ly/Y6GpLn)代码:

// srcImageRep is the NSBitmapImageRep of the source image 
int n = [srcImageRep bitsPerPixel]/8;   // Bytes per pixel 
int w = [srcImageRep pixelsWide]; 
int h = [srcImageRep pixelsHigh]; 
int rowBytes = [srcImageRep bytesPerRow]; 
int i; 

NSImage *destImage = [[NSImage alloc] initWithSize:NSMakeSize(w, h)]; 
NSBitmapImageRep *destImageRep = [[[NSBitmapImageRep alloc] 
     initWithBitmapDataPlanes:NULL 
      pixelsWide:w 
      pixelsHigh:h 
      bitsPerSample:8 
      samplesPerPixel:n 
      hasAlpha:[srcImageRep hasAlpha] 
      isPlanar:NO 
      colorSpaceName:[srcImageRep colorSpaceName] 
      bytesPerRow:rowBytes 
      bitsPerPixel:NULL] autorelease]; 

unsigned char *srcData = [srcImageRep bitmapData]; 
unsigned char *destData = [destImageRep bitmapData]; 

for (i = 0; i < rowBytes * h; i++) 
    *(destData + i) = 255 - *(srcData + i); 

[destImage addRepresentation:destImageRep]; 
相关问题