public void DrawSurface(CGContext ctx, CGRect viewBounds, SkiaSharp.SKImageInfo info, SkiaSharp.SKSurface surface)
        {
            if (info.Width == 0 || info.Height == 0)
            {
                return;
            }

            surface.Canvas.Flush();

            // draw the image onto the context
            using (var colorSpace = CGColorSpace.CreateDeviceRGB())
                using (var image = new CGImage(info.Width, info.Height, BitsPerByte, info.BytesPerPixel * BitsPerByte, info.RowBytes, colorSpace, BitmapFlags, dataProvider, null, false, CGColorRenderingIntent.Default))
                {
#if __IOS__ || __TVOS__ || __WATCHOS__ || HAS_UNO
                    // we need to flip the image as we are mixing CoreGraphics and UIKit functions:
                    // https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW26
                    ctx.SaveState();
                    ctx.TranslateCTM(0, viewBounds.Height);
                    ctx.ScaleCTM(1, -1);
                    // draw the image
                    ctx.DrawImage(viewBounds, image);
                    ctx.RestoreState();
#elif __MACOS__
                    // draw the image
                    ctx.DrawImage(viewBounds, image);
#else
#error Plaform-specific code missing
#endif
                }
        }
        private SkiaSharp.SKSurface CreateSurface(out SkiaSharp.SKImageInfo info)
        {
            // get context details
            info = this.info;

            // if there are no pixels, clean up and return
            if (info.Width == 0 || info.Height == 0)
            {
                Dispose();
                return(null);
            }

            // if the memory size has changed, then reset the underlying memory
            if (bitmap?.Handle == IntPtr.Zero || bitmap?.Width != info.Width || bitmap?.Height != info.Height)
            {
                FreeBitmap();
            }

            // create the bitmap data if we need it
            if (bitmap == null)
            {
                bitmap = ABitmap.CreateBitmap(info.Width, info.Height, ABitmap.Config.Argb8888);
            }

            return(SkiaSharp.SKSurface.Create(info, bitmap.LockPixels(), info.RowBytes));
        }
        public SkiaSharp.SKSurface CreateSurface(CGRect contentsBounds, nfloat scale, out SkiaSharp.SKImageInfo info)
        {
            contentsBounds.Width  *= scale;
            contentsBounds.Height *= scale;
            // apply a scale
            // get context details
            this.info = info = new SkiaSharp.SKImageInfo((int)contentsBounds.Width, (int)contentsBounds.Height);

            // if there are no pixels, clean up and return
            if (info.Width == 0 || info.Height == 0)
            {
                FreeBitmap();
                this.info = SkiaSharp.SKImageInfo.Empty;
                return(null);
            }

            // if the memory size has changed, then reset the underlying memory
            if (bitmapData?.Length != (nuint)info.BytesSize)
            {
                FreeBitmap();
            }

            // allocate a memory block for the drawing process
            if (bitmapData == null)
            {
                bitmapData   = NSMutableData.FromLength(info.BytesSize);
                dataProvider = new CGDataProvider(bitmapData.MutableBytes, info.BytesSize, Dummy);
                Element.OnSizeChanged((float)contentsBounds.Width, (float)contentsBounds.Height);
            }

            return(SkiaSharp.SKSurface.Create(info, bitmapData.MutableBytes, info.RowBytes));
        }
        void OnCanvasViewPaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args)
        {
            SkiaSharp.SKImageInfo info    = args.Info;
            SkiaSharp.SKSurface   surface = args.Surface;
            SkiaSharp.SKCanvas    canvas  = surface.Canvas;
            canvas.Clear();
            SkiaSharp.SKRect bounds;
            SkiaSharp.SKPath path = SkiaSharp.SKPath.ParseSvgPathData((string)this.Resources["PathString"]);
            path.GetTightBounds(out bounds);
            SkiaSharp.SKPaint paint = new SkiaSharp.SKPaint
            {
                Style       = SkiaSharp.SKPaintStyle.Stroke,
                Color       = SkiaSharp.SKColors.Black,
                StrokeWidth = 10,
                StrokeCap   = SkiaSharp.SKStrokeCap.Round,
                StrokeJoin  = SkiaSharp.SKStrokeJoin.Round
            };
            canvas.Translate(info.Width / 2, info.Height / 2);

            canvas.Scale(info.Width / (bounds.Width + paint.StrokeWidth),
                         info.Height / (bounds.Height + paint.StrokeWidth));

            canvas.Translate(-bounds.MidX, -bounds.MidY);

            canvas.DrawPath(path, paint);
        }
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         Element?.Gesture?.Clear();
         RemoveObserver(this, keyPath: boundsPath);
         RemoveObserver(this, keyPath: framePath);
     }
     base.Dispose(disposing);
     // make sure we free the image data
     FreeBitmap();
     info = SkiaSharp.SKImageInfo.Empty;
 }
예제 #6
0
        public static SkiaSharp.SKBitmap?ToBitmap(this SkiaSharp.SKPicture skPicture, SkiaSharp.SKColor background, float scaleX, float scaleY, SkiaSharp.SKColorType skColorType, SkiaSharp.SKAlphaType skAlphaType, SkiaSharp.SKColorSpace skColorSpace)
        {
            var width  = skPicture.CullRect.Width * scaleX;
            var height = skPicture.CullRect.Height * scaleY;

            if (!(width > 0) || !(height > 0))
            {
                return(null);
            }
            var skImageInfo = new SkiaSharp.SKImageInfo((int)width, (int)height, skColorType, skAlphaType, skColorSpace);
            var skBitmap    = new SkiaSharp.SKBitmap(skImageInfo);

            using var skCanvas = new SkiaSharp.SKCanvas(skBitmap);
            Draw(skPicture, background, scaleX, scaleY, skCanvas);
            return(skBitmap);
        }
        protected void UpdateCanvasSize(int w, int h, float density = 1f)
        {
            if (density != 1)
            {
                info = new SkiaSharp.SKImageInfo((int)(w / density), (int)(h / density), SkiaSharp.SKColorType.Rgba8888, SkiaSharp.SKAlphaType.Premul);
            }
            else
            {
                info = new SkiaSharp.SKImageInfo(w, h, SkiaSharp.SKColorType.Rgba8888, SkiaSharp.SKAlphaType.Premul);
            }

            // if there are no pixels, clean up
            if (info.Width == 0 || info.Height == 0)
            {
                FreeBitmap();
            }
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _disposed = true;
                if (element != null)
                {
                    element.SurfaceInvalidated -= Invalidate;
                    element.Gesture?.Clear();
                }

                OnFocusChangeListener = null;
                _tracker?.Dispose();
            }
            FreeBitmap();
            info = SkiaSharp.SKImageInfo.Empty;
            base.Dispose(disposing);
        }
예제 #9
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            if (designMode)
            {
                return;
            }

            if (Visibility != Visibility.Visible)
            {
                return;
            }

            var size = CreateSize(out var scaleX, out var scaleY);

            if (size.Width <= 0 || size.Height <= 0)
            {
                return;
            }

            var info = new SkiaSharp.SKImageInfo(size.Width, size.Height, SkiaSharp.SKImageInfo.PlatformColorType, SkiaSharp.SKAlphaType.Premul, SKSvgSettings.s_srgb);

            // reset the bitmap if the size has changed
            if (bitmap == null || info.Width != bitmap.PixelWidth || info.Height != bitmap.PixelHeight)
            {
                bitmap = new WriteableBitmap(info.Width, size.Height, 96 * scaleX, 96 * scaleY, PixelFormats.Pbgra32, null);
            }

            // draw on the bitmap
            bitmap.Lock();
            using (var surface = SkiaSharp.SKSurface.Create(info, bitmap.BackBuffer, bitmap.BackBufferStride))
            {
                OnPaintSurface(new SKPaintSurfaceEventArgs(surface, info));
            }

            // draw the bitmap to the screen
            bitmap.AddDirtyRect(new Int32Rect(0, 0, info.Width, size.Height));
            bitmap.Unlock();
            drawingContext.DrawImage(bitmap, new Rect(0, 0, ActualWidth, ActualHeight));
        }
 public SKPaintSurfaceEventArgs(SkiaSharp.SKSurface surface, SkiaSharp.SKImageInfo info)
 {
     Surface = surface;
     Info    = info;
 }
 protected override void OnDetachedFromWindow()
 {
     FreeBitmap();
     info = SkiaSharp.SKImageInfo.Empty;
     base.OnDetachedFromWindow();
 }
 void UpdateCanvasInfo(CGRect frame, System.nfloat scale)
 {
     info = new SkiaSharp.SKImageInfo((int)(Frame.Width * scale), (int)(frame.Height * scale));
 }
예제 #13
0
        public static BitmapInfo GetBitmapInfo(SkiaSharp.SKImageInfo info, int rowBytes = 0)
        {
            var fmt = ToPixelFormat((info.ColorType, info.AlphaType));

            return(new BitmapInfo(info.Width, info.Height, fmt, Math.Max(info.RowBytes, rowBytes)));
        }