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