我有一个应用程序,用户可以在加载的图像上自由绘制。他选择了铅笔颜色,并开始绘制图像。
除此之外,他还可以用手指向下和向上缩放图像,这就是我遇到问题的地方。
缩放后,当绘制到图像上时,它变得模糊,并且奇怪地缩小..
扩展代码:
void ScaleImage (UIPinchGestureRecognizer gestureRecognizer)
{
AdjustAnchorPoint (gestureRecognizer);
if (gestureRecognizer.State == UIGestureRecognizerState.Began || gestureRecognizer.State == UIGestureRecognizerState.Changed) {
gestureRecognizer.View.Transform *= CGAffineTransform.MakeScale (gestureRecognizer.Scale, gestureRecognizer.Scale);
gestureRecognizer.Scale = 1;
}
}
绘图代码:
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
if (!canDraw)
return;
UITouch touch = (UITouch)touches.AnyObject;
lastPoint = touch.LocationInView (MyImageView);
}
public override void TouchesMoved (NSSet touches, UIEvent evt)
{
base.TouchesMoved (touches, evt);
if (!canDraw)
return;
UITouch touch = (UITouch)touches.AnyObject;
PointF currentPoint = touch.LocationInView (MyImageView);
UIGraphics.BeginImageContext (MyImageView.Frame.Size);
MyImageView.Image.Draw (new RectangleF (
0, 0,
MyImageView.Frame.Size.Width,
MyImageView.Frame.Size.Height));
CGContext ctx = UIGraphics.GetCurrentContext ();
ctx.SetLineCap (CGLineCap.Round);
ctx.SetLineWidth (5.0f);
ctx.SetRGBStrokeColor (red, green, blue, 1);
CGPath path = new CGPath ();
path.MoveToPoint(MyImageView.Transform, lastPoint.X, lastPoint.Y);
path.AddLineToPoint (MyImageView.Transform, currentPoint.X, currentPoint.Y);
ctx.AddPath (path);
ctx.DrawPath (CGPathDrawingMode.Stroke);
MyImageView.Image = UIGraphics.GetImageFromCurrentImageContext ();
UIGraphics.EndImageContext ();
lastPoint = currentPoint;
}
提前致谢!
答案 0 :(得分:3)
我通过使用Bezier Paths而不是Core Graphics来实现它。
您可以在此处找到有关Bezier路径的一些背景信息: https://developer.apple.com/library/ios/documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html
由于我想实现一个Undo按钮,我创建了一个用于存储该行颜色的Class,以及相应的Path:
public class VESLine{
public UIBezierPath Path {
get;
set;
}
public UIColor Color {
get;
set;
}
public byte Index {
get;
set;
}
}
相应地修改了TouchesBegan
事件,以创建新的UIBezierPath对象,将其存储在数组中,连同其颜色和索引以及触摸位置:
public override void TouchesBegan (MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
IndexCount++;
UIBezierPath path = new UIBezierPath ();
path.LineWidth = 5.0f;
UITouch touch = (UITouch)touches.AnyObject;
previousPoint1 = touch.PreviousLocationInView (this);
PointF p = touch.LocationInView (this);
path.MoveTo (p);
InvokeOnMainThread (() => {
this.SetNeedsDisplay ();
});
currentPath = path;
VESLine line = new VESLine () {
Path = currentPath,
Color = StrokeColor,
Index = IndexCount
};
lines.Add(line);
}
TouchesMoved
事件也被修改,通过使用QuadCurve而不是常规线创建平滑的线路径。我还调用SetNeedsDisplay
方法来强制进行视图绘制:
public override void TouchesMoved (MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
UITouch touch = (UITouch)touches.AnyObject;
PointF p = touch.LocationInView (this);
if (Math.Abs (p.X - previousPoint1.X) >= 4 ||
Math.Abs (p.Y - previousPoint1.Y) >= 4) {
PointF cP = new PointF ((p.X + previousPoint1.X) / 2, (p.Y + previousPoint1.Y) / 2);
currentPath.AddQuadCurveToPoint (cP, previousPoint1);
previousPoint1 = p;
}
else
currentPath.AddLineTo (p);
InvokeOnMainThread (() => {
this.SetNeedsDisplay ();
});
}
TouchesEnded
和TouchesCancelled
将重绘视图:
public override void TouchesEnded (MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
InvokeOnMainThread (() => {
this.SetNeedsDisplay ();
});
}
public override void TouchesCancelled (MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
InvokeOnMainThread (() => {
this.SetNeedsDisplay ();
});
}
最后,重写Draw
方法以迭代路径数组,使用相应的颜色绘制每个路径:
public override void Draw (System.Drawing.RectangleF rect)
{
foreach (VESLine p in lines) {
p.Color.SetStroke ();
p.Path.Stroke ();
}
}