【问题标题】:Cocoa NSPoint to Quartz NSPoint - Flip Y cordinateCocoa NSPoint 到 Quartz NSPoint - 翻转 Y 坐标
【发布时间】:2019-01-01 10:07:41
【问题描述】:

在macOS编程中,我们知道

  • Quartz 使用原点 (0, 0) 位于主显示屏左上角的坐标空间。增加 y 会下降。
  • Cocoa 使用坐标空间,其中原点 (0, 0) 位于主显示屏的左下角,并且 y 增加向上。

现在我正在使用 Quartz API - CGImageCreateWithImageInRect 来裁剪图像,该图像将矩形作为参数。矩形的 Y 原点来自 Cocoa 的 mousedown 事件。

因此我在倒置的位置收获作物......

我试过这段代码来翻转我的cropRect中的Y坐标

 //Get the point in MouseDragged event
 NSPoint currentPoint = [self.view convertPoint:[theEvent locationInWindow] fromView:nil];
 CGRect nsRect = CGRectMake(currentPoint.x , currentPoint.y,   
                                  circleSizeW,  circleSizeH);
 //Now Flip the Y please!
 CGFloat flippedY = self.imageView.frame.size.height - NSMaxY(nsRectFlippedY);
 CGRect cropRect = CGRectMake(currentPoint.x, flippedY, circleSizeW, circleSizeH);

但是对于顶部的区域,我错误的 FlippedY 坐标。 如果我在视图的顶部边缘附近单击,我会翻转 Y = 510 到 515 在顶部边缘,它应该在 0 到 10 之间:-|

谁能指出正确可靠的翻转方式 在这种情况下的 Y 坐标?谢谢!

这是 GitHub 中突出显示问题的示例项目 https://github.com/kamleshgk/SampleMacOSApp

【问题讨论】:

  • 当你说“矩形的 Y 原点来自 Cocoa 的 mousedown 事件”时,你的意思是 -locationInWindow?也就是说,顾名思义,是相对于窗口的坐标,而不是屏幕坐标。
  • 什么是nsRect
  • @KenThomases 是的,来自点的 Y 来自此代码 - NSPoint currentPoint = [self.view convertPoint:[theEvent locationInWindow] fromView:nil];
  • @Willeke nsRect 是包含此代码中 Y 点的矩形 NSPoint currentPoint = [self.view convertPoint:[theEvent locationInWindow] fromView:nil];
  • @Willeke 请参阅 nsRect 问题中的更新代码!谢谢!

标签: macos cocoa quartz-graphics


【解决方案1】:

正如 Charles 所提到的,您使用的 Core Graphics API 需要相对于图像(而不是屏幕)的坐标。重要的是将事件位置从窗口坐标转换为与图像位置最接近的视图,然后相对于同一视图的边界(而不是框架)翻转它。所以:

NSView *relevantView = /* only you know which view */;
NSPoint currentPoint = [relevantView convertPoint:[theEvent locationInWindow] fromView:nil];
// currentPoint is in Cocoa's y-up coordinate system, relative to relevantView, which hopefully corresponds to your image's location

currentPoint.y = NSMaxY(relevantView.bounds) - currentPoint.y;
// currentPoint is now flipped to be in Quartz's y-down coordinate system, still relative to relevantView/your image

【讨论】:

    【解决方案2】:

    您传递给CGImageCreateWithImageInRect 的矩形应该是相对于输入图像大小的坐标,而不是屏幕坐标。假设输入图像的大小与您将点转换到的视图的大小相匹配,您应该能够通过从图像的高度而不是屏幕高度中减去矩形的角来实现这一点。

    【讨论】:

    • 同意。 View 上的 ImageView 和大小相同。当我单击 ImageView 的顶部时,单击点的 Y 坐标在 0 到 10 之间。我得到的是底部的裁剪图像,而不是顶部的图像 - 我单击的位置。所以你建议这个? CGFloat flippedY = NSMaxY(imageview.height) - NSMaxY(nsRect);
    • @kamyFC 只是imageview.height,而不是NSMaxY()
    • @KenThomases CGFloat flippedY = self.imageView.image.size.height - NSMaxY(nsRectFlippedY); .........使用此代码 - 我将 Y 值设为 725 - 如果我在图像顶部单击鼠标 .......... CGFloat flippedY = self.imageView.frame.size.height - NSMaxY(nsRectFlippedY); ..... 使用此代码,我将 Y 值设为 -72 - 如果 i MouseClick 在图像顶部.......第二个解决方案很接近。但并不安静......
    • @KenThomases 我在使用建议的公式后在问题中添加了屏幕截图。
    • imageView是窗口的内容视图吗?或者它是内容视图的子视图(或进一步的后代)?是否可以将其定位,使其在顶部被部分切断?在您的代码 sn-p 中,您将点转换为 self.view 的坐标空间,但您将它相对于 self.imageView 翻转。您应该对两者使用相同的视图。您选择哪个取决于您希望最终的矩形与什么相关。
    猜你喜欢
    • 2023-03-21
    • 2011-04-30
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    相关资源
    最近更新 更多