2010-11-26 97 views
0

更新
没关系制作PNG位图:-)
想通了使用bitmapImageRepForCachingDisplayInRect & cacheDisplayInRect:toBitmapImageRep:
不过,我会留下这个问题留给后人。遇到麻烦的一个NSView


我工作的一个小应用程序,除其他事项外,有一个NSView子,吸引了一堆bezierPaths的。我希望能够将绘制的结果保存为EPS或PNG。

该视图正在屏幕外的窗口中绘制(出于缩放的原因),并且即使它返回了正确的EPS数据,我似乎也无法从中获取任何有用的位图数据。

EPS是没有问题的(我只是把NSData-dataWithEPSInsideRect:写到一个文件中),但我似乎无法得到一个PNG位图。

如果我尝试调用:

[self lockFocus]; 
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:self.bounds]; 
[self unlockFocus]; 
return rep; 
从一个类中的方法,我加入的NSView

,我得到无用的白色PNG数据出来的时候我尝试representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]

奇怪的是,如果我尝试打电话lockFocus/initBitmapWith ../ unlockFocus方法从视图(或其类的方法),我得到一个异常说其祖先的视图或一个被隐藏。嗯,是的,它在屏幕外(离屏窗口已经被延期启动:顺便说一句,所以它应该画)。

所以我可以得到无用的数据或我可以得到一个异常。不是很棒。如果我制作一个包含EPS表示的NSImage和一个(无用的)白色位图,其中两者都应该是视图边界的大小,则位图表示总是比每个像素20个像素/单位更窄边界。不知道为什么! EPS是正确的大小。

由于这都可以涉及到如何在屏幕外窗口的创建,下面是该代码(从一个NSView类别)

- (NSWindow*)placeInOffscreenWindow { 
NSRect windowBounds = { { -1000.0 , -1000.0 } , self.bounds.size }; 
NSWindow *hiddenWindow = [[NSWindow alloc] initWithContentRect: windowBounds 
                 styleMask: NSTitledWindowMask | NSClosableWindowMask 
                  backing: NSBackingStoreNonretained 
                  defer: NO]; 

[[hiddenWindow contentView] addSubview:self]; 
return hiddenWindow; 
} 

任何想法,将不胜感激!

回答

2

结束了使用bitmapImageRepForCachingDisplayInRect: & cacheDisplayInRect:toBitmapImageRep:代替

1

我建议你创建一个NSImage,锁定它的焦点,告诉视图绘制其边界,并解锁焦点,然后ask the image to create a CGImage,然后将其传递给CGImageDestination以写出PNG数据/文件。

+0

@Hosey:谢谢你的提示,但其实我结束了使用bitmapImageRepForCachingDisplayInRect:cacheDisplayInRect:toBitmapImageRep:相反,这似乎很好地工作。但我可能会尝试一下你的建议,只是为了学习一些东西。顺便说一下,我使用的脚本Rentzsch使您的建议警告 - 谢谢! “Hardass模式”为我提供了大量的重构思路,所以它现在好多了!另外,因为我只是从Obj-C/Cocoa开始,这是一个很大的帮助! – Flambino 2010-11-27 03:16:09

+0

我发现CGImageDestination比NSBitmapImageRep的`representationUsingType:properties:`方法更可靠,但它们*应该*同样做得很好。至于警告帖子:不客气。 ☺ – 2010-11-27 04:26:51