NSRect vs CGRect:y轴反转
Posted
技术标签:
【中文标题】NSRect vs CGRect:y轴反转【英文标题】:NSRect vs CGRect: y-axis inversion 【发布时间】:2013-06-12 04:38:33 【问题描述】:所以我正在尝试将 NSRect 转换为 CGRect。我使用了NSRectToCGRect()
,它可以很好地复制所有内容,但没有考虑 y 原点轴。
问题:(0,0) 的 CGRect 原点在左上角。 NSRect 原点 (0,0) 在左下角。
因此,NSRect (0,0,100,100)
框位于屏幕左下方,而CGRect (0,0,100,100)
框位于屏幕左上方。
我有一个通过基本数学修正 y 原点的 hack:
fixedOriginY = screenHeight - NSRect.size.height - NSRect.origin.y
因此,NSRect (0,0,100,100)
的等价物实际上是 CGRect (0,800,100,100)
(在我的 900 像素高度 MBA 上)。但是我不喜欢这样,我感觉它会破裂/出现视网膜问题或未来的并发症。
有没有人有关于如何正确地将 NSRect 转换为 CGRect 的解决方案或想法?
【问题讨论】:
是什么让您认为 CoreGraphics 的原点位于左上角?我只能立即找到对它的间接引用,但请参阅 developer.apple.com/library/ios/#documentation/2DDrawing/… — 搜索文本“Core Graphics 框架使用的默认坐标系是基于 LLO 的”。 (LLO = 左下原点) NSWindow 框架属性是一个 NSRect,所以我把它放在 0,0(屏幕左下角)。我将该帧转换为 CGRect,使用 CGDisplayCreateImageForRect(displays[0], windowCGRect) 截取屏幕截图。屏幕截图是屏幕左上角的。 不要认为这是CGRect
和NSRect
之间的区别。它们都只是简单的结构,它们的值仅相对于某个坐标系(提供或使用矩形的代码的坐标系)有意义。在这种情况下,AppKit 的屏幕坐标系和 CG 的显示空间坐标系之间存在差异,如this answer 中所述。
如果你只想截取一个窗口,你可以使用CGWindowListCreateImage()
而不是CGDisplayCreateImageForRect()
。
【参考方案1】:
矩形的原点是在左上角还是左下角取决于您使用矩形的坐标系。它不取决于您使用的是CGRect
还是NSRect
。
通常,AppKit 使用以左下角为原点的坐标系。同样,您创建的 CGContext
将原点放在左下方。
另一方面,Quartz Event Services 和 Quartz Display Services 将原点放在左上角。 UIKit(在 iOS 上)将原点放在左上角。您可以在 NSView
子类(在 OS X 上)中覆盖 isFlipped
,使其原点位于左上角。
当您将矩形从传统(左下原点)转换为翻转(左上原点)坐标系时,您的基本数学是必要且正确的。
【讨论】:
窗口框架(例如-[NSWindow frame]
)位于屏幕坐标空间,其原点是左下角。 Quartz Display Services 使用全局或局部桌面坐标空间,其原点是对应的左上角。以上是关于NSRect vs CGRect:y轴反转的主要内容,如果未能解决你的问题,请参考以下文章