【问题标题】:How to draw inside the black edges in iOS SDK with OpenGL ES?如何使用 OpenGL ES 在 iOS SDK 中绘制黑色边缘?
【发布时间】:2018-06-20 09:26:25
【问题描述】:

参考下面的图片,如何在不使用遮罩的情况下在黑色边缘内绘制[例如-如果我们想在帽内绘制,完美地我们需要使用画笔工具填充帽]。

我们已经使用洪水填充算法实现了桶工具。

Refer [IMAGE 4] 这种类型的绘图是错误的,所以我们只需要在黑边参考 [IMAGE 2] 和 [IMAGE 3] 内绘制。

我们需要在 iOS SDK 中实现这个,

这两种方法我已经试过了-

  1. 我已经记录了一个特定区域的坐标,它滞后太多,内存泄漏就在那里。这不是一个好方法

  2. 我必须在后台使用水桶工具(洪水填充算法)填充特定区域,然后尝试匹配触摸点的颜色。它也不能提供完美的输出。

[图片 1]

[图片 2]

[图片 3]

[图片 4]

【问题讨论】:

  • 此功能的哪一部分是 OpenGL,您试图在堆栈的哪个级别完成它?这种用户交互是驱动的吗?内容是任意的还是固定的? 2D 插图的绘图填充和诸如此类的东西不太适合原始 OpenGL 工作。您是否单独使用 GL 进行输出渲染并在更高级别管理绘图和位图?或者是其他东西。下面斯蒂芬的回答适合这里更传统(和互动)的方法。
  • @BenZotto developer.apple.com/library/archive/samplecode/GLPaint/… 我正在使用苹果 gl 油漆并且我已经实现了很多草图。现在我需要实现上述功能。
  • 在下面的答案中,如何获取此图像轮廓(黑边)的贝塞尔路径。你能给出任何想法吗
  • 请注意Open GL ES is deprecated in iOS 12,见developer.apple.com/ios/whats-new。也像@BenZotto 提到的那样,OpenGL 可能更复杂,不太适合这种要求。您可能想看看:raywenderlich.com/87899/make-simple-drawing-app-uikit-swift.
  • @ram,如果可以,请分享示例代码!提前致谢!!!

标签: ios objective-c swift opengl-es


【解决方案1】:

有几种可能的方法。例如,可以使用纯矢量方法。但是,单个图纸的转换可能非常耗时。

更务实的做法可能如下:

接近

您可以定义一个 Bézier 路径列表 (UIBezierPath),每个路径描述一个可以独立绘制的区域。

贝塞尔路径有两个用途:

  • 确定中风从哪个区域开始
  • 将用户绘图限制在该区域

如何在黑线内完美绘制

如果您使给定绘图的背景透明,您可以创建用户的绘图操作,并在黑线绘图下方进行剪切。这意味着 Bézier 路径不必完美,只要足够准确即可。

图层/剪辑

接下来的步骤是:

  • 最初显示给定的图形
  • 确定用户开始绘制的贝塞尔路径
  • 剪辑到确定的贝塞尔路径
  • 使用剪辑绘制用户笔画
  • 在给定的透明线图上绘制

快速演示

这是一个简短的演示,展示了当用户使用所描述的绘图顺序开始在剪切的 Bézier 路径中绘图时的样子(另请参见下面的代码 sn-ps):

代码片段

贝塞尔路径示例

bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 55.94, y: 60.19))
bezierPath.addCurve(to: CGPoint(x: 50.32, y: 94.09), controlPoint1: CGPoint(x: 56.92, y: 59.69), controlPoint2: CGPoint(x: 55.25, y: 73.99))
bezierPath.addCurve(to: CGPoint(x: 48.81, y: 115.93), controlPoint1: CGPoint(x: 46.9, y: 107.97), controlPoint2: CGPoint(x: 49.09, y: 115.33))
bezierPath.addCurve(to: CGPoint(x: 74.36, y: 146.45), controlPoint1: CGPoint(x: 50.56, y: 127.4), controlPoint2: CGPoint(x: 60.85, y: 141.06))
bezierPath.addCurve(to: CGPoint(x: 119.11, y: 126.29), controlPoint1: CGPoint(x: 93.52, y: 141.34), controlPoint2: CGPoint(x: 107.61, y: 134.31))
bezierPath.addCurve(to: CGPoint(x: 223.27, y: 93.88), controlPoint1: CGPoint(x: 150.33, y: 112.49), controlPoint2: CGPoint(x: 183.59, y: 100.44))
bezierPath.addCurve(to: CGPoint(x: 300.41, y: 69.01), controlPoint1: CGPoint(x: 250.68, y: 87.71), controlPoint2: CGPoint(x: 276.22, y: 79.2))
bezierPath.addCurve(to: CGPoint(x: 297.23, y: 59.69), controlPoint1: CGPoint(x: 301.38, y: 65.82), controlPoint2: CGPoint(x: 300.22, y: 62.01))
bezierPath.addCurve(to: CGPoint(x: 212.85, y: 38.3), controlPoint1: CGPoint(x: 290.2, y: 62.67), controlPoint2: CGPoint(x: 256.59, y: 52.37))
bezierPath.addCurve(to: CGPoint(x: 137.05, y: 37.2), controlPoint1: CGPoint(x: 191.43, y: 31.36), controlPoint2: CGPoint(x: 158.26, y: 29.92))
bezierPath.addCurve(to: CGPoint(x: 100.74, y: 48.08), controlPoint1: CGPoint(x: 126.18, y: 40.93), controlPoint2: CGPoint(x: 111.78, y: 44.75))
bezierPath.addCurve(to: CGPoint(x: 55.94, y: 60.19), controlPoint1: CGPoint(x: 86.15, y: 52.48), controlPoint2: CGPoint(x: 70.56, y: 56.69))
bezierPath.close()

剪辑到路径

self.currentBezierPath.addClip()

确定触摸是否在封闭的贝塞尔路径内开始

假设 self 是一个自定义视图,可以这样写:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    ...
    let point = touch.location(in: self)
    ...
    let inside = bezierPath.contains(point)
    ...

绘制透明图

首先必须使绘图的背景透明。然后可以以支持透明度的格式存储图形,例如.png。

context.saveGState()
context.scaleBy(x: 1, y: -1)
context.translateBy(x: 0, y: -oOV7Impng.size.height)
context.draw(oOV7Impng.cgImage!, in: CGRect(x: 0, y: 0, width: oOV7Impng.size.width, height: oOV7Impng.size.height))
context.restoreGState()

如果应用中有很多绘图,可以考虑通过编程使图像的背景透明(例如,通过使白色像素透明)。取决于用例。

【讨论】:

  • 我需要在 OpenGL-ES 中为各种草图实现这一点。我也会试试这个,但是如何获得这张图片的贝塞尔路径???
  • 一种可能性:使用矢量图形程序,可以将线条图图像放置在背景中,在顶部手动绘制贝塞尔曲线并将绘图导出为.SVG。在 SVG 中,您会看到 &lt;path d="M55.604,60.201C56.59,59.702 54.918,73.996 49.982,94.096,M 表示初始移动,C 表示 addCurve(控制点 1、控制点 2、到点)。
  • 嗨@StephanSchlecht,我遇到了一些问题,你能帮我吗? stackoverflow.com/questions/52235857/…
  • 很遗憾,我从未使用过您引用的 Github 项目。乍一看,它似乎也提供了一个示例(请参阅自述文件中的屏幕截图)。如果原样使用,示例项目是否可以正常工作?
  • @StephanSchlecht:你能分享一下示例代码吗?我也面临同样的问题
猜你喜欢
  • 2014-11-29
  • 2011-06-13
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多