UIBezierPath半透明描边因多点出现伪影的解决方法咨询
半透明曲线绘制大量点时出现伪影的解决方法
我需要使用半透明颜色绘制曲线,但当曲线包含大量点时会出现异常伪影效果,如何消除该问题?

用户提供的代码:
UIBezierPath * bezierPath = [ UIBezierPath bezierPath ]; bezierPath.lineCapStyle = kCGLineCapRound; bezierPath.lineJoinStyle = kCGLineJoinRound; bezierPath.lineWidth = 80.0; [ bezierPath moveToPoint:CGPointMake(50.0, 50.0) ]; for (int i = 0; i < 900; i++) { [ bezierPath addLineToPoint:CGPointMake(50.0 + i, 50.0) ]; } UIGraphicsImageRendererFormat * format = [ UIGraphicsImageRendererFormat defaultFormat ]; format.scale = 1.0; format.opaque = NO; format.preferredRange = UIGraphicsImageRendererFormatRangeStandard; CGSize size = CGSizeMake(1000.0, 100.0); UIGraphicsImageRenderer * renderer = [ [ UIGraphicsImageRenderer alloc ] initWithSize:size format:format ]; UIImage * image = [ renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { [ [ UIColor clearColor ] setFill ]; [ [ UIColor colorWithWhite:0.0 alpha:0.5 ] setStroke ]; [ bezierPath stroke ]; } ];

问题原因
你当前的代码把一条直线拆成了900段相邻的短线段,每段仅相差1个单位,再加上80的大线宽和圆角线连接设置,半透明状态下这些线段的连接点会反复叠加绘制,导致透明度累积,出现深色伪影。
解决方法
1. 优化路径结构(最直接有效)
如果是直线,完全不需要拆分线段,直接连接起点和终点即可:
UIBezierPath * bezierPath = [UIBezierPath bezierPath]; bezierPath.lineCapStyle = kCGLineCapRound; bezierPath.lineJoinStyle = kCGLineJoinRound; bezierPath.lineWidth = 80.0; [bezierPath moveToPoint:CGPointMake(50.0, 50.0)]; // 直接连接到终点,替代循环生成的900段线段 [bezierPath addLineToPoint:CGPointMake(50.0 + 900, 50.0)];
2. 针对复杂曲线的通用方案
如果实际场景是折线或平滑曲线,无法合并成单条线段:
- 过滤近邻点:遍历点数组,只保留距离上一个点超过阈值的点,减少不必要的线段连接,避免叠加绘制。
- 调整渲染逻辑:先绘制不透明线条,再整体叠加半透明效果,避免局部叠加:
UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { [[UIColor clearColor] setFill]; // 先绘制完全不透明的线条 [[UIColor blackColor] setStroke]; [bezierPath stroke]; // 用混合模式整体叠加半透明效果 [[UIColor colorWithWhite:0.0 alpha:0.5] setFill]; UIRectFillUsingBlendMode(CGRectMake(0,0,size.width,size.height), kCGBlendModeMultiply); }];
内容的提问来源于stack exchange,提问作者Alexandr Hotko
相关产品推荐
相关产品推荐

