public SkiaSharp.SKPoint PlaceInfoToSKPoint(PraxisCore.StandaloneDbTables.PlaceInfo2 pi, ImageStats imgstats) { SkiaSharp.SKPoint point = new SkiaSharp.SKPoint(); point.X = (float)((pi.lonCenter - imgstats.area.WestLongitude) * (1 / imgstats.degreesPerPixelX)); point.Y = (float)((pi.latCenter - imgstats.area.SouthLatitude) * (1 / imgstats.degreesPerPixelY)); return(point); }
public static SKShader CreateLinearGradient (SKPoint start, SKPoint end, SKColor [] colors, float [] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) throw new ArgumentNullException (nameof (colors)); if (colorPos == null) { return GetObject<SKShader> (SkiaApi.sk_shader_new_linear_gradient (new SKPoint [] { start, end }, colors, IntPtr.Zero, colors.Length, mode, ref localMatrix)); } else { if (colors.Length != colorPos.Length) throw new ArgumentException ("The number of colors must match the number of color positions."); return GetObject<SKShader> (SkiaApi.sk_shader_new_linear_gradient (new SKPoint [] { start, end }, colors, colorPos, colors.Length, mode, ref localMatrix)); } }
public SkiaSharp.SKPoint[] PlaceInfoToSKPoints(PraxisCore.StandaloneDbTables.PlaceInfo2 pi, ImageStats info) { float heightMod = (float)pi.height / 2; float widthMod = (float)pi.width / 2; var points = new SkiaSharp.SKPoint[5]; points[0] = new SkiaSharp.SKPoint((float)(pi.lonCenter + widthMod), (float)(pi.latCenter + heightMod)); //upper right corner points[1] = new SkiaSharp.SKPoint((float)(pi.lonCenter + widthMod), (float)(pi.latCenter - heightMod)); //lower right points[2] = new SkiaSharp.SKPoint((float)(pi.lonCenter - widthMod), (float)(pi.latCenter - heightMod)); //lower left points[3] = new SkiaSharp.SKPoint((float)(pi.lonCenter - widthMod), (float)(pi.latCenter + heightMod)); //upper left points[4] = new SkiaSharp.SKPoint((float)(pi.lonCenter + widthMod), (float)(pi.latCenter + heightMod)); //upper right corner again for a closed shape. //points is now a geometric area. Convert to image area points = points.Select(p => new SkiaSharp.SKPoint((float)((p.X - info.area.WestLongitude) * (1 / info.degreesPerPixelX)), (float)((p.Y - info.area.SouthLatitude) * (1 / info.degreesPerPixelY)))).ToArray(); return(points); }
void DrawArcFromTo (SKCanvas canvas, SKPaint paint, int xc, int yc, int radius, float startAngleInDegrees, float endAngleInDegrees) { if (radius <= 0) return; int x = radius; int y = 0; int cd2 = 0; // convert degrees to radians var startAngleRadians = startAngleInDegrees * Math.PI / 180; var endAngleRadians = endAngleInDegrees * Math.PI / 180; // find x,y coordinates for start and end points var startx = xc + radius * (float)Math.Cos (startAngleRadians); var starty = yc + radius * (float)Math.Sin (startAngleRadians); var startPoint = new SKPoint (startx, starty); var endx = xc + radius * (float)Math.Cos (endAngleRadians); var endy = yc + radius * (float)Math.Sin (endAngleRadians); var endPoint = new SKPoint (endx, endy); // build the path var points = new List<SKPoint> (); // 4 cardinal points var p00 = new SKPoint (xc - radius, yc); var ap00 = Math.Atan2 (p00.Y - yc, p00.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)ap00, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p00); var p01 = new SKPoint (xc + radius, yc); var ap01 = Math.Atan2 (p01.Y - yc, p01.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)ap01, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p01); var p02 = new SKPoint (xc, yc - radius); var ap02 = Math.Atan2 (p02.Y - yc, p02.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)ap02, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p02); var p03 = new SKPoint (xc, yc + radius); var ap03 = Math.Atan2 (p03.Y - yc, p03.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)ap03, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p03); while (x > y) { x--; y++; cd2 -= x - y; if (cd2 < 0) cd2 += x++; // 8 octants - listed clockwise // right hemisphere, starting at the top var p0 = new SKPoint (xc + y, yc - x); var arp0 = Math.Atan2 (p0.Y - yc, p0.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp0, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p0); var p1 = new SKPoint (xc + x, yc - y); var arp1 = Math.Atan2 (p1.Y - yc, p1.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp1, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p1); var p2 = new SKPoint (xc + x, yc + y); var arp2 = Math.Atan2 (p2.Y - yc, p2.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp2, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p2); var p3 = new SKPoint (xc + y, yc + x); var arp3 = Math.Atan2 (p3.Y - yc, p3.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp3, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p3); // left hemisphere, continuing around from the bottom var p4 = new SKPoint (xc - y, yc + x); var arp4 = Math.Atan2 (p4.Y - yc, p4.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp4, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p4); var p5 = new SKPoint (xc - x, yc + y); var arp5 = Math.Atan2 (p5.Y - yc, p5.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp5, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p5); var p6 = new SKPoint (xc - x, yc - y); var arp6 = Math.Atan2 (p6.Y - yc, p6.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp6, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p6); var p7 = new SKPoint (xc - y, yc - x); var arp7 = Math.Atan2 (p7.Y - yc, p7.X - xc) * 180 / Math.PI; if (IsAngleBetween ((int)arp7, (int)startAngleInDegrees, (int)endAngleInDegrees)) points.Add (p7); } canvas.DrawPoints (SKPointMode.Points, points.ToArray (), paint); }
// DrawPoint public void DrawPoint(SKPoint p, SKPaint paint) { DrawPoint(p.X, p.Y, paint); }
public static SKRect Create(SKPoint location, SKSize size) { return SKRect.Create(location.X, location.Y, size.Width, size.Height); }
public static SKPointI Truncate(SKPoint value) { int x, y; checked { x = (int)value.X; y = (int)value.Y; } return new SKPointI(x, y); }
public static SKPoint Add(SKPoint pt, SKPoint sz) => pt + sz;
public void Scale(SKPoint size) { SkiaApi.sk_canvas_scale (Handle, size.X, size.Y); }
public bool GetTangent (float distance, out SKPoint tangent) { return SkiaApi.sk_pathmeasure_get_pos_tan (Handle, distance, IntPtr.Zero, out tangent); }
public void DrawText(byte[] text, SKPoint p, SKPaint paint) { DrawText(text, p.X, p.Y, paint); }
// DrawText public void DrawText(string text, SKPoint p, SKPaint paint) { DrawText(text, p.X, p.Y, paint); }
// DrawSurface public void DrawSurface(SKSurface surface, SKPoint p, SKPaint paint = null) { DrawSurface(surface, p.X, p.Y, paint); }
// DrawBitmap public void DrawBitmap(SKBitmap bitmap, SKPoint p, SKPaint paint = null) { DrawBitmap(bitmap, p.X, p.Y, paint); }
public void DrawPicture(SKPicture picture, SKPoint p, SKPaint paint = null) { DrawPicture(picture, p.X, p.Y, paint); }
// DrawImage public void DrawImage(SKImage image, SKPoint p, SKPaint paint = null) { DrawImage(image, p.X, p.Y, paint); }
public void DrawPoint(SKPoint p, SKColor color) { DrawPoint(p.X, p.Y, color); }
/// <summary> /// Creates a matrix that rotates about a specified center. /// </summary> /// <param name="angle">Angle of rotation in radians.</param> /// <param name="center">The center of the rotation.</param> /// <returns>The created rotation matrix.</returns> public static SKMatrix Rotation(double angle, SKPoint center) { return Multiply( Multiply( Translate(-center.X, -center.Y), Rotation(angle)), Translate(center.X, center.Y)); }
public bool GetPositionAndTangent (float distance, out SKPoint position, out SKPoint tangent) { return SkiaApi.sk_pathmeasure_get_pos_tan (Handle, distance, out position, out tangent); }
public void DrawText(IntPtr buffer, int length, SKPoint p, SKPaint paint) { DrawText(buffer, length, p.X, p.Y, paint); }
public void DrawText(string text, SKPoint [] points, SKPaint paint) { if (text == null) throw new ArgumentNullException ("text"); if (paint == null) throw new ArgumentNullException (nameof (paint)); if (points == null) throw new ArgumentNullException ("points"); var bytes = Util.GetEncodedText (text, paint.TextEncoding); SkiaApi.sk_canvas_draw_pos_text (Handle, bytes, bytes.Length, points, paint.Handle); }
// DrawTextOnPath public void DrawTextOnPath(string text, SKPath path, SKPoint offset, SKPaint paint) { DrawTextOnPath(text, path, offset, true, paint); }
public void Translate(SKPoint point) { SkiaApi.sk_canvas_translate (Handle, point.X, point.Y); }
// DrawLine public void DrawLine(SKPoint p0, SKPoint p1, SKPaint paint) { DrawLine(p0.X, p0.Y, p1.X, p1.Y, paint); }
public static SKPointI Ceiling(SKPoint value) { int x, y; checked { x = (int)Math.Ceiling(value.X); y = (int)Math.Ceiling(value.Y); } return new SKPointI(x, y); }
public void DrawTextOnPath(byte[] text, SKPath path, SKPoint offset, SKPaint paint) { DrawTextOnPath(text, path, offset.X, offset.Y, paint); }
public bool Contains(SKPoint pt) { return Contains(pt.X, pt.Y); }
public void DrawTextOnPath(IntPtr buffer, int length, SKPath path, SKPoint offset, SKPaint paint) { DrawTextOnPath(buffer, length, path, offset.X, offset.Y, paint); }
public void MapVectors(SKPoint[] result, SKPoint[] vectors) { if (result == null) throw new ArgumentNullException(nameof(result)); if (vectors == null) throw new ArgumentNullException(nameof(vectors)); int dl = result.Length; if (dl != vectors.Length) throw new ArgumentException("Buffers must be the same size."); unsafe { fixed (SKPoint* rp = &result[0]) { fixed (SKPoint* pp = &vectors[0]) { SkiaApi.sk_matrix_map_vectors(ref this, (IntPtr)rp, (IntPtr)pp, dl); } } } }
public void DrawNamedDestinationAnnotation(SKPoint point, SKData value) { SkiaApi.sk_canvas_draw_named_destination_annotation(Handle, &point, value == null ? IntPtr.Zero : value.Handle); }
static SKPoint RotatePoint (SKPoint pointToRotate, SKPoint centerPoint, double angleInDegrees) { double angleInRadians = angleInDegrees * (Math.PI / 180); double cosTheta = Math.Cos (angleInRadians); double sinTheta = Math.Sin (angleInRadians); return new SKPoint { X = (int) (cosTheta * (pointToRotate.X - centerPoint.X) - sinTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.X), Y = (int) (sinTheta * (pointToRotate.X - centerPoint.X) + cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y) }; }
public SKImage ApplyImageFilter(SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPoint outOffset) { if (filter == null) { throw new ArgumentNullException(nameof(filter)); } return(GetObject <SKImage> (SkiaApi.sk_image_make_with_filter(Handle, filter.Handle, ref subset, ref clipBounds, out outSubset, out outOffset))); }
void DrawArc (SKCanvas canvas, SKPaint paint, double startAngleInDegrees, double endAngleInDegrees) { // find center and radius var centerx = (float)Bounds.Width / 2; var centery = (float)Bounds.Height / 2; var radius = Bounds.Width < Bounds.Height ? (float)Bounds.Width / 2 : (float)Bounds.Height / 2; var w = 0.558f; // convert degrees to radians var startAngleRadians = startAngleInDegrees * Math.PI / 180; var endAngleRadians = endAngleInDegrees * Math.PI / 180; // find x,y coordinates for start and end points var startx = centerx + radius * (float)Math.Cos (startAngleRadians); var starty = centery + radius * (float)Math.Sin (startAngleRadians); var startPoint = new SKPoint (startx, starty); var endx = centerx + radius * (float)Math.Cos (endAngleRadians); var endy = centery + radius * (float)Math.Sin (endAngleRadians); var endPoint = new SKPoint (endx, endy); // find linear distance & midpoint between start and end points var linearDistance = Math.Sqrt(Math.Pow(endy - starty, 2) / Math.Pow(endx - startx, 2)); var midx = (startx + endx) / 2; var midy = (starty + endy) / 2; var midPoint = new SKPoint (midx, midy); // rotate end point 45 degrees counterclockwise around midpoint to find Conic function anchor var anchorPoint = RotatePoint (endPoint, midPoint, 45); // build path var path = new SKPath (); //path.MoveTo (startx, starty); //path.ConicTo (anchorPoint.X, anchorPoint.Y, endx, endy, w); path.MoveTo (centerx, centery - radius); path.ConicTo (centerx + radius, centery - radius, centerx + radius, centery, w); path.ConicTo (centerx + radius, centery + radius, centerx, centery + radius, w); path.ConicTo (centerx - radius, centery + radius, centerx - radius, centery, w); //path.ConicTo (centerx - radius, centery - radius, centerx, centery - radius, w); //canvas.DrawPoints (SKPointMode.Points, new SKPoint [] { }, paint); canvas.DrawPath (path, paint); }
public void Skew(SKPoint skew) { SkiaApi.sk_canvas_skew(Handle, skew.X, skew.Y); }
/// <summary> /// Transforms a point by this matrix. /// </summary> /// <param name="matrix">The matrix to use as a transformation matrix.</param> /// <param name="point">>The original point to apply the transformation.</param> /// <returns>The result of the transformation for the input point.</returns> public static SKPoint TransformPoint(SKMatrix matrix, SKPoint point) { return new SKPoint( (point.X * matrix.ScaleX) + (point.Y * matrix.SkewX) + matrix.TransX, (point.X * matrix.SkewY) + (point.Y * matrix.ScaleY) + matrix.TransY); }
public static SKPoint Add(SKPoint pt, SKSize sz) { return(new SKPoint(pt.X + sz.Width, pt.Y + sz.Height)); }
public bool GetPosition (float distance, out SKPoint position) { return SkiaApi.sk_pathmeasure_get_pos_tan (Handle, distance, out position, IntPtr.Zero); }
public static SKPoint Subtract(SKPoint pt, SKSize sz) { return(new SKPoint(pt.X - sz.Width, pt.Y - sz.Height)); }
public void DrawPoints(SKPointMode mode, SKPoint [] points, SKPaint paint) { if (paint == null) throw new ArgumentNullException (nameof (paint)); if (points == null) throw new ArgumentNullException (nameof (points)); SkiaApi.sk_canvas_draw_points (Handle, mode, (IntPtr)points.Length, points, paint.Handle); }
public static SKShader CreateTwoPointConicalGradient(SKPoint start, float startRadius, SKPoint end, float endRadius, SKColor [] colors, float [] colorPos, SKShaderTileMode mode, SKMatrix localMatrix) { if (colors == null) { throw new ArgumentNullException(nameof(colors)); } if (colorPos == null) { return(GetObject <SKShader> (SkiaApi.sk_shader_new_two_point_conical_gradient(ref start, startRadius, ref end, endRadius, colors, IntPtr.Zero, colors.Length, mode, ref localMatrix))); } else { if (colors.Length != colorPos.Length) { throw new ArgumentException("The number of colors must match the number of color positions."); } return(GetObject <SKShader> (SkiaApi.sk_shader_new_two_point_conical_gradient(ref start, startRadius, ref end, endRadius, colors, colorPos, colors.Length, mode, ref localMatrix))); } }
public void DrawText(IntPtr buffer, int length, SKPoint[] points, SKPaint paint) { if (buffer == IntPtr.Zero) throw new ArgumentNullException ("buffer"); if (paint == null) throw new ArgumentNullException (nameof (paint)); if (points == null) throw new ArgumentNullException ("points"); SkiaApi.sk_canvas_draw_pos_text (Handle, buffer, length, points, paint.Handle); }
public SKPoint MapPoint(SKPoint point) { return(MapPoint(point.X, point.Y)); }
public void Skew(SKPoint skew) { SkiaApi.sk_canvas_skew (Handle, skew.X, skew.Y); }
public void Offset(SKPoint p) { x += p.x; y += p.y; }
public void Offset(SKPoint p) { Offset(p.X, p.Y); }
public SKSize(SKPoint pt) { w = pt.X; h = pt.Y; }
public static SKPoint Subtract(SKPoint pt, SKPoint sz) => pt - sz;
public static SKPointI Round(SKPoint value) { int x, y; checked { x = (int)Math.Round(value.X); y = (int)Math.Round(value.Y); } return new SKPointI(x, y); }
public SKSize(SKPoint pt) { this.width = pt.X; this.height = pt.Y; }
public void Translate(SKPoint point) { SkiaApi.sk_canvas_translate(Handle, point.X, point.Y); }
public void Offset(SKPoint pos) { Offset(pos.X, pos.Y); }
public void Scale(SKPoint size) { SkiaApi.sk_canvas_scale(Handle, size.X, size.Y); }
public SKPoint[] MapPoints(SKPoint[] points) { if (points == null) throw new ArgumentNullException(nameof(points)); var res = new SKPoint[points.Length]; MapPoints(res, points); return res; }
public SKPoint MapPoint(SKPoint point) { return MapPoint(point.X, point.Y); }
public SKPoint[] MapVectors(SKPoint[] vectors) { if (vectors == null) throw new ArgumentNullException(nameof(vectors)); var res = new SKPoint[vectors.Length]; MapVectors(res, vectors); return res; }
public void DrawCircle(SKPoint c, float radius, SKPaint paint) { DrawCircle(c.X, c.Y, radius, paint); }
internal void Draw(DrawingContextImpl context, SKCanvas canvas, SKPoint origin, DrawingContextImpl.PaintWrapper foreground) { /* TODO: This originated from Native code, it might be useful for debugging character positions as * we improve the FormattedText support. Will need to port this to C# obviously. Rmove when * not needed anymore. SkPaint dpaint; ctx->Canvas->save(); ctx->Canvas->translate(origin.fX, origin.fY); for (int c = 0; c < Lines.size(); c++) { dpaint.setARGB(255, 0, 0, 0); SkRect rc; rc.fLeft = 0; rc.fTop = Lines[c].Top; rc.fRight = Lines[c].Width; rc.fBottom = rc.fTop + LineOffset; ctx->Canvas->drawRect(rc, dpaint); } for (int c = 0; c < Length; c++) { dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10); dpaint.setStyle(SkPaint::kFill_Style); ctx->Canvas->drawRect(Rects[c], dpaint); } ctx->Canvas->restore(); */ SKPaint paint = _paint; IDisposable currd = null; var currentWrapper = foreground; try { SKPaint currFGPaint = ApplyWrapperTo(ref foreground, ref currd, paint); bool hasCusomFGBrushes = _foregroundBrushes.Any(); for (int c = 0; c < _skiaLines.Count; c++) { AvaloniaFormattedTextLine line = _skiaLines[c]; float x = TransformX(origin.X, 0, paint.TextAlign); if (!hasCusomFGBrushes) { var subString = _text.Substring(line.Start, line.Length); canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint); } else { float currX = x; string subStr; int len; for (int i = line.Start; i < line.Start + line.Length;) { var fb = GetNextForegroundBrush(ref line, i, out len); if (fb != null) { //TODO: figure out how to get the brush size currentWrapper = context.CreatePaint(fb, new Size()); } else { if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose(); currentWrapper = foreground; } subStr = _text.Substring(i, len); if (currFGPaint != currentWrapper.Paint) { currFGPaint = ApplyWrapperTo(ref currentWrapper, ref currd, paint); } canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint); i += len; currX += paint.MeasureText(subStr); } } } } finally { if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose(); currd?.Dispose(); } }
} // End Function LoadImage private void DrawImage() { int bitness = System.IntPtr.Size * 8; System.Console.WriteLine(bitness); // https://developer.xamarin.com/guides/cross-platform/drawing/introduction/ // https://developer.xamarin.com/api/type/SkiaSharp.SKSurface/ // https://forums.xamarin.com/discussion/77883/skiasharp-graphics-basics // Make sure the Microsoft Visual C++ 2015 Redistributable is installed if this error occurs: // Unable to load DLL 'libSkiaSharp.dll': The specified module could not be found. using (SKSurface surface = SKSurface.Create(width: 640, height: 480, colorType: SKColorType.Bgra8888, alphaType: SKAlphaType.Premul)) { SKCanvas canvas = surface.Canvas; canvas.Clear(SKColors.Transparent); using (SKPaint paint = new SKPaint()) { // paint.ImageFilter = SKImageFilter.CreateBlur(5, 5); // Dispose ! paint.IsAntialias = true; // paint.Color = new SKColor(0xff, 0x00, 0xff); paint.Color = new SKColor(0x2c, 0x3e, 0x50); paint.StrokeCap = SKStrokeCap.Round; paint.Typeface = SkiaSharp.SKTypeface.FromFamilyName("Impact", SKTypefaceStyle.Bold); paint.TextSize = 12; canvas.DrawText("foobar", 10, 10, paint); // SkiaSharp.SKRect rect = new SkiaSharp.SKRect(); SkiaSharp.SKRect rect = MeasureText("foobar", "Impact", 12, SKTypefaceStyle.Bold); // paint.MeasureText("foobar", ref rect); System.Console.WriteLine(rect); SKRect textOverlayRectangle = new SKRect(); textOverlayRectangle.Left = 9; // x textOverlayRectangle.Top = 10 - rect.Height; // y textOverlayRectangle.Right = textOverlayRectangle.Left + rect.Width; textOverlayRectangle.Bottom = textOverlayRectangle.Top + rect.Height; // canvas.DrawRect(textOverlayRectangle, paint); // https://chromium.googlesource.com/external/skia/+/master/experimental/SkiaExamples/HelloSkiaExample.cpp SkiaSharp.SKPoint[] linearPoints = new SkiaSharp.SKPoint[] { new SkiaSharp.SKPoint(0, 0), new SkiaSharp.SKPoint(300, 300) }; SkiaSharp.SKColor[] linearColors = new SkiaSharp.SKColor[] { SkiaSharp.SKColors.Green, SkiaSharp.SKColors.Black }; // canvas.Restore(); // canvas.Translate(100, 200); // canvas.RotateDegrees(45); // SKShader shader = SkiaSharp.SKShader.CreateLinearGradient(linearPoints[0], linearPoints[1], linearColors, new float[] { 1.0f, 2000.0f }, SKShaderTileMode.Repeat); // paint.Shader = shader; SkiaSharp.SKBitmap shaderPattern = LoadImage(MapProjectPath(@"~mytile.png")); SKShader hatchShader = SkiaSharp.SKShader.CreateBitmap(shaderPattern, SKShaderTileMode.Mirror, SKShaderTileMode.Repeat); paint.Shader = hatchShader; // create the Xamagon path using (SKPath path = new SKPath()) { path.MoveTo(71.4311121f, 56f); path.CubicTo(68.6763107f, 56.0058575f, 65.9796704f, 57.5737917f, 64.5928855f, 59.965729f); path.LineTo(43.0238921f, 97.5342563f); path.CubicTo(41.6587026f, 99.9325978f, 41.6587026f, 103.067402f, 43.0238921f, 105.465744f); path.LineTo(64.5928855f, 143.034271f); path.CubicTo(65.9798162f, 145.426228f, 68.6763107f, 146.994582f, 71.4311121f, 147f); path.LineTo(114.568946f, 147f); path.CubicTo(117.323748f, 146.994143f, 120.020241f, 145.426228f, 121.407172f, 143.034271f); path.LineTo(142.976161f, 105.465744f); path.CubicTo(144.34135f, 103.067402f, 144.341209f, 99.9325978f, 142.976161f, 97.5342563f); path.LineTo(121.407172f, 59.965729f); path.CubicTo(120.020241f, 57.5737917f, 117.323748f, 56.0054182f, 114.568946f, 56f); path.LineTo(71.4311121f, 56f); path.Close(); // draw the Xamagon path canvas.DrawPath(path, paint); } // End Using path // ClipDeviceBounds not ClipBounds canvas.DrawLine(0, 0, canvas.ClipDeviceBounds.Width, canvas.ClipDeviceBounds.Height, paint); canvas.DrawLine(0, canvas.ClipDeviceBounds.Height, canvas.ClipDeviceBounds.Width, 0, paint); canvas.DrawLine(0 + 1, 0, 0 + 1, canvas.ClipDeviceBounds.Height, paint); canvas.DrawLine(0, surface.Canvas.ClipDeviceBounds.Height / 2, canvas.ClipDeviceBounds.Width, canvas.ClipDeviceBounds.Height / 2, paint); canvas.DrawLine(canvas.ClipDeviceBounds.Width - 1, 0 + 1, canvas.ClipDeviceBounds.Width - 1, canvas.ClipDeviceBounds.Height, paint); } // End Using paint // Your drawing code goes here. // surface.Snapshot().Encode(SKImageEncodeFormat.Webp, 80); // SKData p = surface.Snapshot().Encode(); SKData p = surface.Snapshot().Encode(SKImageEncodeFormat.Png, 80); // p.SaveTo() using (System.IO.MemoryStream ms = new System.IO.MemoryStream(p.ToArray())) { this.pictureBox1.Image = System.Drawing.Image.FromStream(ms); } // End Using ms System.IO.File.WriteAllBytes(MapProjectPath("~testme.png"), p.ToArray()); } // End Using surface // this.Close(); } // End Sub