ios - Xamarin iOS - 缩放后绘制到图像上

标签 ios uiimageview drawing xamarin scale

我有一个应用程序,用户可以在加载的图像上自由绘制。他选择了一种铅笔颜色,然后开始在图像上绘图。

除此之外,他还可以使用手指缩小和放大图像,这就是我遇到的问题。

缩放后,绘制到图像上时,图像变得模糊,并且奇怪地缩小..

缩放代码:

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;
        }

提前致谢!

最佳答案

我通过使用 Bezier Paths 而不是 Core Graphics 使其工作。

您可以在此处找到有关贝塞尔路径的一些背景知识: https://developer.apple.com/library/ios/documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html

因为我想实现一个撤消按钮,所以我创建了一个类来存储线条的颜色,以及相应的路径:

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 方法来强制绘制 View :

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 ();
    });
}

TouchesEndedTouchesCancelled 将重绘 View :

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 ();
    }
}

关于ios - Xamarin iOS - 缩放后绘制到图像上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21029440/

相关文章:

ios - 每当圆形图像与 Xcode 中的 CGRect 相交时发出

ios - 从中心点折叠 UIImageView

javascript - 如何使用谷歌地图 DrawManager 以编程方式绘制多边形

ios - Childbrowser 无法在 ios PhoneGap 1.3 中打开网页

ios - 当触地按钮( subview )时,不要处理 super View 上的平移手势

ios - MvxImageViewLoader 默认图像忽略视网膜资源

latex - TikZ 编码 : How to create space between polygon and the nodes it surrounds?

iphone - 如何正确解析 XML 到 iPhone

ios - 想将数据保存在 nsuserdefault 中并将其传输到另一个 Controller 的 TableView 中

iphone - 在 UIView 中逐步绘制 (iPhone)