我正在创建一个绘图应用程序,我想模拟一个扁平的笔尖。令人惊讶的是,它变成了相当困难的任务这是我的解决方案:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.drawingImageView];
currentPoint = CGPointMake(roundf(currentPoint.x), roundf(currentPoint.y));
UIGraphicsBeginImageContext(self.drawingImageView.frame.size);
[self.drawingImageView.image drawInRect:CGRectMake(0, 0, self.drawingImageView.frame.size.width, self.drawingImageView.frame.size.height)];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextMoveToPoint (ctx, lastPoint.x + 8.f, lastPoint.y - 8.f);
CGContextAddLineToPoint(ctx, currentPoint.x + 8.f, currentPoint.y - 8.f);
CGContextAddLineToPoint(ctx, currentPoint.x - 8.f, currentPoint.y + 8.f);
CGContextAddLineToPoint(ctx, lastPoint.x - 8.f, lastPoint.y + 8.f);
CGContextAddLineToPoint(ctx, lastPoint.x + 8.f, lastPoint.y - 8.f);
CGContextClosePath(ctx);
CGContextSetRGBFillColor(ctx, 0, 0, 0, 1);
CGContextDrawPath(ctx, kCGPathFillStroke);
[self.drawingImageView performSelectorInBackground:@selector(setImage:) withObject:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
它的外观如下:
如您所见,边缘不平滑。我想改用UIBezierPath
,但我找不到使用UIBezierPath
实现扁平笔尖效果的方法。也许有一些方法可以改进我的代码或任何其他方法(也许UIBezierPath
)?
我能找到的唯一具有此类绘图风格的应用程序是名为" Khattat"的应用程序。它是关于阿拉伯语的,您应该点击主屏幕上的第二个按钮打开绘画。这是我想要的完美范例。
答案 0 :(得分:2)
问题在于
行UIGraphicsBeginImageContext(self.drawingImageView.frame.size);
这样做是为了创建一个具有图像视图大小的新透明图像上下文,但缩放为1.0
。由于这种比例 - 任何在其中完成的绘图都必须进行上采样才能在2x或3x显示屏上显示 - 因此您的绘图模糊不清。
修复非常简单。你可以使用
UIGraphicsBeginImageContextWithOptions(drawingImageView.frame.size, NO, 0.0);
通过将0.0
传递给scale参数,Core Graphics将自动检测屏幕的比例,并设置上下文的比例以匹配。因此,您在其中执行的任何绘图都将以正确的分辨率完成。
另外,我刚注意到这一行
[self.drawingImageView performSelectorInBackground:@selector(setImage:) withObject:UIGraphicsGetImageFromCurrentImageContext()];
这听起来不是一个好主意。如果您查看UIView
documentation,您会看到Apple说:
必须在主线程上对应用程序的用户界面进行操作。因此,您应该始终从应用程序主线程中运行的代码调用UIView类的方法。
因此你应该这样做
self.drawingImageView.image = UIGraphicsGetImageFromCurrentImageContext()
代替。
关于您使用UIBezierPath
的评论 - 我没有看到此更改带给您的任何明显优势 - 自己绘制路径与使用{{1}一样直接绘图方法。
但是,如果您仍然想要,您当然可以使用UIBezierPath
- 您需要执行以下操作:
UIBezierPath