从 NSView 制作 PNG 位图时遇到问题

发布于 2024-10-04 17:29:05 字数 1686 浏览 3 评论 0原文

更新
没关系:-)
使用 bitmapImageRepForCachingDisplayInRect & 解决了这个问题cacheDisplayInRect:toBitmapImageRep:
不过,我会将这个问题留给后代。


我正在开发一个小应用程序,除其他外,它有一个 NSView 子类,可以绘制一堆 bezierPaths。我希望能够将绘制的结果保存为 EPS 或 PNG。

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

EPS 没问题(我只是将 -dataWithEPSInsideRect: 中的 NSData 写入文件),但我似乎无法获取 PNG 位图。

如果我尝试

[self lockFocus];
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:self.bounds];
[self unlockFocus];
return rep;

从添加到 NSView 的类别方法中调用:,当我尝试 representationUsingType:NSPNGFileType properties:[NSDictionarydictionary] 时,我会从中得到无用的白色 PNG 数据。

奇怪的是,如果我尝试从视图(或其类别方法)外部调用 lockFocus/initBitmapWith../unlockFocus,我会收到一个异常,指出该视图或其祖先之一被隐藏。嗯,是的,它在屏幕外(屏幕外窗口已使用 defer:NO 初始化,顺便说一句,所以它应该绘制)。

所以我要么得到无用的数据,要么得到异常。不太棒。

让我更加困惑的是:如果我制作一个包含 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;
}

任何想法将不胜感激!

Update
Nevermind :-)
Figured it out using bitmapImageRepForCachingDisplayInRect & cacheDisplayInRect:toBitmapImageRep:.
I'll leave the question here for posterity, though.


I'm working on a little application that, among other things, has an NSView subclass that draws a bunch of bezierPaths. I'd like to be able to save the drawn result as either EPS or PNG.

The view is being drawn in an offscreen window (for scaling reasons), and even though it returns the correct EPS data, I can't seem to get any useful bitmap data from it.

EPS is no problem (I simply write the NSData from -dataWithEPSInsideRect: to a file), but I can't seem to get a PNG bitmap.

If I try calling:

[self lockFocus];
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:self.bounds];
[self unlockFocus];
return rep;

from a category method I've added to NSView, I get useless white PNG data out of it when I try representationUsingType:NSPNGFileType properties:[NSDictionary dictionary].

Strangely, if I try calling lockFocus/initBitmapWith../unlockFocus from outside the view (or its category methods), I get an exception saying that the view or one of its ancestors is hidden. And well, yes, it's offscreen (the offscreen window's been init'ed with defer:NO, by the way, so it should paint).

So I can either get useless data or I can get an exception. Not awesome.

To add to my confusion: If I make an NSImage containing an EPS representation, and a (useless) white bitmap, where both should be the size of the view's bounds, the bitmap representation is always 20 pixels/units narrower than the bounds. No idea why! The EPS is the correct size.

Since this may all be related to how the offscreen window's created, here's the code for that (from the NSView category)

- (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;
}

Any ideas would be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦回旧景 2024-10-11 17:29:05

最终使用 bitmapImageRepForCachingDisplayInRect: & cacheDisplayInRect:toBitmapImageRep:

Ended up using bitmapImageRepForCachingDisplayInRect: & cacheDisplayInRect:toBitmapImageRep: instead

与风相奔跑 2024-10-11 17:29:05

我建议您创建一个 NSImage,将焦点锁定在其上,告诉视图绘制其边界,然后解锁焦点,然后 要求图像创建CGImage,然后通过到 CGImageDestination 写出 PNG 数据/文件。

I suggest you create an NSImage, lock focus on it, tell the view to draw its bounds, and unlock focus, then ask the image to create a CGImage, then pass that to a CGImageDestination to write out the PNG data/file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文