Swift实现iOS涂色App:如何避免为图像特定区域上色?
涂色App的CoreImage与Vision库实现问题解答
我正在开发一款涂色App,以此学习iOS的CoreImage与Vision库。App会向用户展示白底黑线的草图供上色(示例图:
),目前用Canvas视图实现上色功能,支持指定线宽与颜色,但遇到三个核心挑战,以下是对应的解决方案:
1. 阻止用户为原图黑线区域上色
核心思路是生成原图黑线区域的蒙版,在绘制前做校验:
- 用Vision的
VNContourDetectionRequest检测原图的黑线轮廓,将这些轮廓区域标记为不可绘制区域,生成蒙版图像。 - 在
Canvas的触摸绘制回调中,获取当前触摸点的坐标,先检查蒙版对应位置是否属于黑线区域:若是则跳过绘制逻辑,若否则执行上色操作。 - 也可以用CoreImage的阈值滤镜将原图转为黑白二值图,黑色部分即为黑线区域,直接用该二值图作为蒙版,通过判断触摸点像素值来拦截绘制。
2. 允许修改用户手绘的黑色区域,但保护原图黑线
关键是区分原图黑线和用户绘制内容,采用分层绘制方案:
- 将绘制区域分为三层:底层是不可修改的原图,中间层存储用户所有绘制内容(包括黑色),顶层是标记原图黑线的蒙版。
- 当用户执行擦除或覆盖颜色操作时,先校验触摸点是否属于原图黑线区域:若是则不处理,若否则对中间层的用户绘制内容进行修改。
- 也可单独维护一个用户绘制像素缓冲区,所有上色操作仅更新该缓冲区;显示时将原图、用户缓冲区、蒙版合成,修改黑色区域时直接操作用户缓冲区即可,原图黑线始终不受影响。
3. 适配不同尺寸草图的最佳方案
重点保证蒙版与Canvas视图的坐标匹配:
- 统一坐标系统:加载草图时将其缩放到
Canvas视图的尺寸,同时对预处理生成的蒙版执行相同的缩放变换,确保触摸点与蒙版位置一一对应。 - 利用Vision的坐标转换:使用
VNImageRequestHandler时设置imageCropAndScaleOption参数,将轮廓检测结果直接转换到Canvas的视图坐标系,无需手动处理缩放偏移。 - 预缓存蒙版:每加载一张新草图时,提前预处理生成对应的蒙版并缓存,用户切换草图时直接调用缓存的蒙版,提升响应速度。
我已尝试通过轮廓检测方案识别黑线,相关源代码可参考对应实现。
内容的提问来源于stack exchange,提问作者abs8090
相关产品推荐
相关产品推荐

