如何使用OpenGL ES在iOS SDK中绘制黑色边缘?

ram*_*ram 7 opengl-es objective-c ios swift

请参考下面附图,如何在不使用遮蔽的情况下在黑色边缘内进行涂漆[例如 - 如果我们想要在盖子内部绘制,我们需要使用刷子工具填充盖子].

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

参考[图4]这种类型的图纸是错误的,所以我们只需要在黑色边缘内绘制参考[图像2]和[图像3].

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

我已经尝试过这两种方式 -

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

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

[图片1]

在此输入图像描述

[图片2]

在此输入图像描述

[图3]

在此输入图像描述

[图片4]

在此输入图像描述

Ste*_*cht 1

有几种可能的方法。例如,可以使用纯基于向量的方法。然而,各个图纸的转换可能非常耗时。

\n\n

更务实的方法可能如下:

\n\n

方法

\n\n

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

\n\n

B\xc3\xa9zier 路径有两个用途:

\n\n
    \n
  • 确定中风在哪个区域开始
  • \n
  • 限制用户绘图在此区域
  • \n
\n\n

如何在黑色线条内完美绘制

\n\n

如果将给定绘图的背景设置为透明,则可以通过在黑线绘图下方进行剪辑来创建用户的绘图操作。这意味着 B\xc3\xa9zier 路径不必是完美的,它只需足够准确即可。

\n\n

图层/剪裁

\n\n

步骤将是:

\n\n
    \n
  • 最初显示给定的绘图
  • \n
  • 确定用户开始绘图的 B\xc3\xa9zier 路径
  • \n
  • 剪辑到确定的 B\xc3\xa9zier 路径
  • \n
  • 通过剪辑绘制用户笔画
  • \n
  • 在给定的透明线条图上绘制
  • \n
\n\n

快速演示

\n\n

这是一个简短的演示,展示了当用户开始使用所描述的绘制顺序在剪切的 B\xc3\xa9zier 路径中绘制时的外观(另请参阅下面的代码片段):

\n\n

快速演示

\n\n

代码片段

\n\n

贝塞尔路径示例

\n\n
bezierPath = UIBezierPath()\nbezierPath.move(to: CGPoint(x: 55.94, y: 60.19))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.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))\nbezierPath.close()\n
Run Code Online (Sandbox Code Playgroud)\n\n

剪辑到路径

\n\n
self.currentBezierPath.addClip()\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

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

绘制透明图

\n\n

第一个必须使绘图的背景透明。然后,可以将绘图存储为支持透明度的格式,例如 .png。

\n\n
context.saveGState()\ncontext.scaleBy(x: 1, y: -1)\ncontext.translateBy(x: 0, y: -oOV7Impng.size.height)\ncontext.draw(oOV7Impng.cgImage!, in: CGRect(x: 0, y: 0, width: oOV7Impng.size.width, height: oOV7Impng.size.height))\ncontext.restoreGState()\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n