Example #1
0
        void MapPanned(NSPanGestureRecognizer obj)
        {
            var p = obj.TranslationInView(CanvasView);

            var pp = new SKPoint((float)(_canvasSize.Width * p.X / CanvasView.Bounds.Width),
                                 (float)(_canvasSize.Height - (_canvasSize.Height * p.Y / CanvasView.Bounds.Height)));

            pp = _im.MapPoint(pp);

            if (!_isPanZoom)
            {
                StartPanZoom(new SKPoint((float)pp.X, (float)pp.Y));
            }
            if (_isPanZoom)
            {
                _totalDistance = new SKPoint((float)p.X, 1 - (float)p.Y);
                DoPanZoom(_startM, _startAnchorPt, _totalDistance, _totalScale);
            }
            NSCursor.ClosedHandCursor.Set();
            if (obj.State == NSGestureRecognizerState.Ended)
            {
                NSCursor.ArrowCursor.Set();
                _isPanZoom = false;
                _m.TryInvert(out _im);
            }
        }
        protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
        {
            base.OnPaintSurface(args);

            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear(SKColors.Gray);

            // Calculate rectangle for displaying bitmap
            float  scale      = Math.Min((float)info.Width / bitmap.Width, (float)info.Height / bitmap.Height);
            float  x          = (info.Width - scale * bitmap.Width) / 2;
            float  y          = (info.Height - scale * bitmap.Height) / 2;
            SKRect bitmapRect = new SKRect(x, y, x + scale * bitmap.Width, y + scale * bitmap.Height);

            canvas.DrawBitmap(bitmap, bitmapRect);

            // Calculate a matrix transform for displaying the cropping rectangle
            SKMatrix bitmapScaleMatrix = SKMatrix.MakeIdentity();

            bitmapScaleMatrix.SetScaleTranslate(scale, scale, x, y);

            // Display rectangle
            SKRect scaledCropRect = bitmapScaleMatrix.MapRect(croppingRect.Rect);

            canvas.DrawRect(scaledCropRect, edgeStroke);

            // Display heavier corners
            using (SKPath path = new SKPath())
            {
                path.MoveTo(scaledCropRect.Left, scaledCropRect.Top + CORNER);
                path.LineTo(scaledCropRect.Left, scaledCropRect.Top);
                path.LineTo(scaledCropRect.Left + CORNER, scaledCropRect.Top);

                path.MoveTo(scaledCropRect.Right - CORNER, scaledCropRect.Top);
                path.LineTo(scaledCropRect.Right, scaledCropRect.Top);
                path.LineTo(scaledCropRect.Right, scaledCropRect.Top + CORNER);

                path.MoveTo(scaledCropRect.Right, scaledCropRect.Bottom - CORNER);
                path.LineTo(scaledCropRect.Right, scaledCropRect.Bottom);
                path.LineTo(scaledCropRect.Right - CORNER, scaledCropRect.Bottom);

                path.MoveTo(scaledCropRect.Left + CORNER, scaledCropRect.Bottom);
                path.LineTo(scaledCropRect.Left, scaledCropRect.Bottom);
                path.LineTo(scaledCropRect.Left, scaledCropRect.Bottom - CORNER);

                canvas.DrawPath(path, cornerStroke);
            }

            // Invert the transform for touch tracking
            bitmapScaleMatrix.TryInvert(out inverseBitmapMatrix);
        }
Example #3
0
 public RotatedGrid(SKMatrix matrix, Rectangle containingRec, int numFrames)
 {
     GridContainer = containingRec;
     CellWidth     = (float)dist(containingRec.A, containingRec.B) / numFrames;
     CellHeight    = (float)dist(containingRec.A, containingRec.D) / numFrames;
     FromGrid      = matrix;
     //try to invert, if unsucessful ToGrid will be all 0's
     if (!FromGrid.TryInvert(out toGrid))
     {
         toGrid = new SKMatrix();
     }
 }
Example #4
0
        private SKMatrix ComputeMatrix(SKSize size, SKPoint ptUL, SKPoint ptUR, SKPoint ptLL, SKPoint?ptLR = null)
        {
            // Scale transform
            SKMatrix S = SKMatrix.CreateScale(1 / size.Width, 1 / size.Height);

            // Affine transform
            SKMatrix A = new SKMatrix
            {
                ScaleX = ptUR.X - ptUL.X,
                SkewY  = ptUR.Y - ptUL.Y,
                SkewX  = ptLL.X - ptUL.X,
                ScaleY = ptLL.Y - ptUL.Y,
                TransX = ptUL.X,
                TransY = ptUL.Y,
                Persp2 = 1
            };

            // Non-Affine transform
            SKMatrix N = SKMatrix.CreateIdentity();

            if (ptLR.HasValue)
            {
                SKMatrix inverseA;
                A.TryInvert(out inverseA);
                SKPoint abPoint = inverseA.MapPoint(ptLR.Value);
                float   a       = abPoint.X;
                float   b       = abPoint.Y;

                float scaleX = a / (a + b - 1);
                float scaleY = b / (a + b - 1);

                N = new SKMatrix
                {
                    ScaleX = scaleX,
                    ScaleY = scaleY,
                    Persp0 = scaleX - 1,
                    Persp1 = scaleY - 1,
                    Persp2 = 1
                };
            }

            // Multiply S * N * A
            SKMatrix result = SKMatrix.CreateIdentity();

            SKMatrix.PostConcat(ref result, S);
            SKMatrix.PostConcat(ref result, N);
            SKMatrix.PostConcat(ref result, A);

            return(result);
        }
Example #5
0
        public void MoveByVector(SKPoint vector)
        {
            SKMatrix invertedMatrix;

            if (!Matrix.TryInvert(out invertedMatrix))
            {
                return;
            }
            var resultPoint = invertedMatrix.MapVector(vector.X, vector.Y);

            SKMatrix.PreConcat(ref Matrix, SKMatrix.MakeTranslation(resultPoint.X, resultPoint.Y));
            if (CenterBoundary.IsEmpty)
            {
                return;
            }
            var center = GetCenter();

            if (!CenterBoundary.Contains(center))
            {
                //rollback
                SKMatrix.PreConcat(ref Matrix, SKMatrix.MakeTranslation(-resultPoint.X, -resultPoint.Y));
            }
        }
Example #6
0
        protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
        {
            base.OnPaintSurface(args);

            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear(SkiaHelper.backgroundColor);

            // 计算显示位图的矩形
            var rect = SkiaHelper.CalculateRectangle(new SKRect(0, 0, info.Width, info.Height), bitmap);

            canvas.DrawBitmap(bitmap, rect.rect);

            // 计算用于显示裁剪矩形的矩阵变换
            SKMatrix bitmapScaleMatrix = SKMatrix.CreateIdentity();

            SKMatrix.CreateScaleTranslation(rect.scaleX, rect.scaleX, rect.rect.Left, rect.rect.Top);

            // 显示矩形
            SKRect scaledCropRect = bitmapScaleMatrix.MapRect(croppingRect.Rect);


            using (SKPaint edgeStroke = new SKPaint())
            {
                edgeStroke.Style       = SKPaintStyle.Stroke;
                edgeStroke.Color       = SKColors.White;
                edgeStroke.StrokeWidth = 3;
                edgeStroke.IsAntialias = true;
                canvas.DrawRect(scaledCropRect, edgeStroke);
            }

            canvas.DrawSurrounding(rect.rect, scaledCropRect, SKColors.Gray.WithAlpha(190));

            // Display heavier corners
            using (SKPaint cornerStroke = new SKPaint())
                using (SKPath path = new SKPath())
                {
                    cornerStroke.Style       = SKPaintStyle.Stroke;
                    cornerStroke.Color       = SKColors.White;
                    cornerStroke.StrokeWidth = 7;

                    path.MoveTo(scaledCropRect.Left, scaledCropRect.Top + corner);
                    path.LineTo(scaledCropRect.Left, scaledCropRect.Top);
                    path.LineTo(scaledCropRect.Left + corner, scaledCropRect.Top);

                    path.MoveTo(scaledCropRect.Right - corner, scaledCropRect.Top);
                    path.LineTo(scaledCropRect.Right, scaledCropRect.Top);
                    path.LineTo(scaledCropRect.Right, scaledCropRect.Top + corner);

                    path.MoveTo(scaledCropRect.Right, scaledCropRect.Bottom - corner);
                    path.LineTo(scaledCropRect.Right, scaledCropRect.Bottom);
                    path.LineTo(scaledCropRect.Right - corner, scaledCropRect.Bottom);

                    path.MoveTo(scaledCropRect.Left + corner, scaledCropRect.Bottom);
                    path.LineTo(scaledCropRect.Left, scaledCropRect.Bottom);
                    path.LineTo(scaledCropRect.Left, scaledCropRect.Bottom - corner);

                    canvas.DrawPath(path, cornerStroke);
                }

            // 反转变换以进行触摸跟踪
            bitmapScaleMatrix.TryInvert(out inverseBitmapMatrix);
        }
Example #7
0
        public void Invert()
        {
            //// copied from SkMatrix::invertNonIdentity
            //// see: https://github.com/google/skia/blob/master/src/core/SkMatrix.cpp
            //if (IsIdentity)
            //    return;

            //var m = _m;

            //bool isScaleMatrix = m.ScaleX != 1f || m.ScaleY != 1f;
            //bool isTranslateMatrix = m.TransX != 0f || m.TransY != 0f;
            //bool isRotateMatrix = m.SkewX != 0f || m.SkewX != 0f;

            //if (!isRotateMatrix && isScaleMatrix && isTranslateMatrix)
            //{
            //    var invX = m.ScaleX;
            //    var invY = m.ScaleY;
            //    if (invX == 0 || invY == 0)
            //    {
            //        // not invertible
            //        return;
            //    }
            //    invX = 1/invX;
            //    invY = 1/invY;
            //    m.SkewX = 0;
            //    m.SkewY = 0;
            //    m.Persp0 = 0;
            //    m.Persp1 = 0;

            //    m.ScaleX = invX;
            //    m.ScaleY = invY;
            //    m.Persp2 = 1;
            //    m.TransX = -m.TransX*invX;
            //    m.TransY = -m.TransY*invY;

            //    _m = m;
            //    return;
            //}
            //else if (!isRotateMatrix && isTranslateMatrix)
            //{
            //    m.TransX = -m.TransX;
            //    m.TransY = -m.TransY;
            //    _m = m;
            //    return;
            //}

            //var m = _m;
            //float det = m.ScaleX * (m.ScaleY * m.Persp2 - m.Persp1 * m.TransY) -
            // m.SkewX * (m.SkewY * m.Persp2 - m.TransY * m.Persp0) +
            // m.TransX * (m.SkewY * m.Persp1 - m.ScaleY * m.Persp0);

            //float invdet = 1 / det;

            //var m1 = new SKMatrix();
            //m1.ScaleX = (m.ScaleY * m.Persp2 - m.Persp1 * m.TransY) * invdet;
            //m1.SkewX = (m.TransX * m.Persp1 - m.SkewX * m.Persp2) * invdet;
            //m1.TransX = (m.SkewX * m.TransY - m.TransX * m.ScaleY) * invdet;
            //m1.SkewY = (m.TransY * m.Persp0 - m.SkewY * m.Persp2) * invdet;
            //m1.ScaleY = (m.ScaleX * m.Persp2 - m.TransX * m.Persp0) * invdet;
            //m1.TransY = (m.SkewY * m.TransX - m.ScaleX * m.TransY) * invdet;
            //m1.Persp0 = (m.SkewY * m.Persp1 - m.Persp0 * m.ScaleY) * invdet;
            //m1.Persp1 = (m.Persp0 * m.SkewX - m.ScaleX * m.Persp1) * invdet;
            //m1.Persp2 = (m.ScaleX * m.ScaleY - m.SkewY * m.SkewX) * invdet;
            //_m = m1;

            SKMatrix m;

            if (_m.TryInvert(out m))
            {
                _m = m;
            }
        }