UIBezierPath绘制的视图的模糊屏幕截图

我使用UIBezierPath方法和coretext绘制我的graphics视图。 我使用addQuadCurveToPoint:controlPoint:方法在图上绘制曲线。 我也使用CATiledLayer来渲染大数据集在X轴上的graphics。 我在图像上下文中绘制了我的整个graphics,并在我的整个视图中绘制了这个图像。 以下是我的代码。

 - (void)drawImage{ UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0); // Draw Curves [self drawDiagonal]; UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); [screenshot retain]; UIGraphicsEndImageContext(); } - (void)drawRect:(CGRect)rect{ NSLog(@"Draw iN rect with Bounds: %@",NSStringFromCGRect(rect)); [screenshot drawInRect:self.frame]; } 

然而在屏幕截图中,两点之间的曲线并不平滑。 我也在我的信息plist中将“抗锯齿渲染”设置为“是”。 请看截图。 在这里输入图像说明

我们不得不看看你是如何构buildUIBezierPath ,但以我的经验UIBezierPath ,对于平滑的曲线,关键问题是曲线的控制点和曲线的特定段的终点之间的线的斜率是否等于曲线起点的下一段与其控制点之间的斜率。 我发现使用addCurveToPoint而不是addQuadCurveToPoint绘制一般的smoooth曲线比较addQuadCurveToPoint ,所以我可以更一般地调整起始和结束控制点来满足这个标准。

为了说明这一点,我通常绘制UIBezierPath曲线的方式是在曲线上有一个点的数组,以及曲线在该点上应该采用的angular度,然后是addCurveToPoint控制点的“权重”(即多远出控制点应该是)。 因此,我使用这些参数来指定UIBezierPath的第二个控制点和UIBezierPath的下一个段的第一个控制点。 所以,例如:

 @interface BezierPoint : NSObject @property CGPoint point; @property CGFloat angle; @property CGFloat weight; @end @implementation BezierPoint - (id)initWithPoint:(CGPoint)point angle:(CGFloat)angle weight:(CGFloat)weight { self = [super init]; if (self) { self.point = point; self.angle = angle; self.weight = weight; } return self; } @end 

然后,我如何使用它的一个例子:

 - (void)loadBezierPointsArray { // clearly, you'd do whatever is appropriate for your chart. // this is just a unclosed loop. But it illustrates the idea. CGPoint startPoint = CGPointMake(self.view.frame.size.width / 2.0, 50); _bezierPoints = [NSMutableArray arrayWithObjects: [[BezierPoint alloc] initWithPoint:CGPointMake(startPoint.x, startPoint.y) angle:M_PI_2 * 0.05 weight:100.0 / 1.7], [[BezierPoint alloc] initWithPoint:CGPointMake(startPoint.x + 100.0, startPoint.y + 70.0) angle:M_PI_2 weight:70.0 / 1.7], [[BezierPoint alloc] initWithPoint:CGPointMake(startPoint.x, startPoint.y + 140.0) angle:M_PI weight:100.0 / 1.7], [[BezierPoint alloc] initWithPoint:CGPointMake(startPoint.x - 100.0, startPoint.y + 70.0) angle:M_PI_2 * 3.0 weight:70.0 / 1.7], [[BezierPoint alloc] initWithPoint:CGPointMake(startPoint.x + 10.0, startPoint.y + 10) angle:0.0 weight:100.0 / 1.7], nil]; } - (CGPoint)calculateForwardControlPoint:(NSUInteger)index { BezierPoint *bezierPoint = _bezierPoints[index]; return CGPointMake(bezierPoint.point.x + cosf(bezierPoint.angle) * bezierPoint.weight, bezierPoint.point.y + sinf(bezierPoint.angle) * bezierPoint.weight); } - (CGPoint)calculateReverseControlPoint:(NSUInteger)index { BezierPoint *bezierPoint = _bezierPoints[index]; return CGPointMake(bezierPoint.point.x - cosf(bezierPoint.angle) * bezierPoint.weight, bezierPoint.point.y - sinf(bezierPoint.angle) * bezierPoint.weight); } - (UIBezierPath *)bezierPath { UIBezierPath *path = [UIBezierPath bezierPath]; BezierPoint *bezierPoint = _bezierPoints[0]; [path moveToPoint:bezierPoint.point]; for (NSInteger i = 1; i < [_bezierPoints count]; i++) { bezierPoint = _bezierPoints[i]; [path addCurveToPoint:bezierPoint.point controlPoint1:[self calculateForwardControlPoint:i - 1] controlPoint2:[self calculateReverseControlPoint:i]]; } return path; } 

当我把这个渲染成一个UIImage (使用下面的代码)时,我没有看到图像的任何软化,但是可以肯定的是图像不一样。 (我将capture的图像与通过按下物理设备上的电源和主屏幕button同时捕获的屏幕快照进行比较)。

如果你看到一些软化,我会build议renderInContext (如下所示)。 我想知道如果你把图像写成JPG(这是有损的)。 也许尝试PNG,如果你使用JPG。

 - (void)drawBezier { UIBezierPath *path = [self bezierPath]; CAShapeLayer *oval = [[CAShapeLayer alloc] init]; oval.path = path.CGPath; oval.strokeColor = [UIColor redColor].CGColor; oval.fillColor = [UIColor clearColor].CGColor; oval.lineWidth = 5.0; oval.strokeStart = 0.0; oval.strokeEnd = 1.0; [self.view.layer addSublayer:oval]; } - (void)capture { UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); [self.view.layer renderInContext:context]; UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // save the image NSData *data = UIImagePNGRepresentation(screenshot); NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *imagePath = [documentsPath stringByAppendingPathComponent:@"image.png"]; [data writeToFile:imagePath atomically:YES]; // send it to myself so I can look at the file NSURL *url = [NSURL fileURLWithPath:imagePath]; UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:@[url] applicationActivities:nil]; [self presentViewController:controller animated:YES completion:nil]; }