private void SkCanvasView_OnPaintSurface(object sender, SKPaintSurfaceEventArgs e) { var skImageInfo = e.Info; var skSurface = e.Surface; var skCanvas = skSurface.Canvas; var skCanvasWidth = skImageInfo.Width; var skCanvasHeight = skImageInfo.Height; skCanvas.Clear(SKColors.White); // Draw gradient rainbow Color spectrum using (var paint = new SKPaint()) { paint.IsAntialias = true; // Initiate the primary Color list // picked up from Google Web Color Picker var colors = new SKColor[] { new SKColor(255, 0, 0), // Red new SKColor(255, 255, 0), // Yellow new SKColor(0, 255, 0), // Green (Lime) new SKColor(0, 255, 255), // Aqua new SKColor(0, 0, 255), // Blue new SKColor(255, 0, 255), // Fuchsia new SKColor(255, 0, 0), // Red }; // create the gradient shader between Colors using (var shader = SKShader.CreateLinearGradient( new SKPoint(0, 0), new SKPoint(skCanvasWidth, 0), colors, null, SKShaderTileMode.Clamp)) { paint.Shader = shader; skCanvas.DrawPaint(paint); } } // Draw darker gradient spectrum using (var paint = new SKPaint()) { paint.IsAntialias = true; // Initiate the darkened primary color list var colors = new SKColor[] { SKColors.Transparent, SKColors.Black }; // create the gradient shader using (var shader = SKShader.CreateLinearGradient( new SKPoint(0, 0), new SKPoint(0, skCanvasHeight), colors, null, SKShaderTileMode.Clamp)) { paint.Shader = shader; skCanvas.DrawPaint(paint); } } // Picking the Pixel Color values on the Touch Point // Represent the color of the current Touch point SKColor touchPointColor; //// Inefficient: causes memory overload errors //using (var skImage = skSurface.Snapshot()) //{ // using (var skData = skImage.Encode(SKEncodedImageFormat.Webp, 100)) // { // if (skData != null) // { // using (SKBitmap bitmap = SKBitmap.Decode(skData)) // { // touchPointColor = bitmap.GetPixel( // (int)_lastTouchPoint.X, (int)_lastTouchPoint.Y); // } // } // } //} // Efficient and fast // https://forums.xamarin.com/discussion/92899/read-a-pixel-info-from-a-canvas // create the 1x1 bitmap (auto allocates the pixel buffer) using (SKBitmap bitmap = new SKBitmap(skImageInfo)) { // get the pixel buffer for the bitmap IntPtr dstpixels = bitmap.GetPixels(); // read the surface into the bitmap skSurface.ReadPixels(skImageInfo, dstpixels, skImageInfo.RowBytes, (int)_lastTouchPoint.X, (int)_lastTouchPoint.Y); // access the color touchPointColor = bitmap.GetPixel(0, 0); } // Painting the Touch point using (SKPaint paintTouchPoint = new SKPaint()) { paintTouchPoint.Style = SKPaintStyle.Fill; paintTouchPoint.Color = SKColors.White; paintTouchPoint.IsAntialias = true; // Outer circle (Ring) var outerRingRadius = ((float)skCanvasWidth / (float)skCanvasHeight) * (float)18; skCanvas.DrawCircle( _lastTouchPoint.X, _lastTouchPoint.Y, outerRingRadius, paintTouchPoint); // Draw another circle with picked color paintTouchPoint.Color = touchPointColor; // Outer circle (Ring) var innerRingRadius = ((float)skCanvasWidth / (float)skCanvasHeight) * (float)12; skCanvas.DrawCircle( _lastTouchPoint.X, _lastTouchPoint.Y, innerRingRadius, paintTouchPoint); } // Set selected color PickedColor = touchPointColor.ToFormsColor(); PickedColorChanged?.Invoke(this, PickedColor); }
private void SkCanvasView_OnPaintSurface(object sender, SKPaintSurfaceEventArgs e) { var skImageInfo = e.Info; var skSurface = e.Surface; var skCanvas = skSurface.Canvas; var skCanvasWidth = skImageInfo.Width; var skCanvasHeight = skImageInfo.Height; skCanvas.Clear(SKColors.White); // Draw gradient rainbow Color spectrum using (var paint = new SKPaint()) { paint.IsAntialias = true; System.Collections.Generic.List <SKColor> colors = new System.Collections.Generic.List <SKColor>(); ColorList.ForEach((color) => { colors.Add(Color.FromHex(color).ToSKColor()); }); // create the gradient shader between Colors using (var shader = SKShader.CreateLinearGradient( new SKPoint(0, 0), ColorListDirection == ColorListDirection.Horizontal ? new SKPoint(skCanvasWidth, 0) : new SKPoint(0, skCanvasHeight), colors.ToArray(), null, SKShaderTileMode.Clamp)) { paint.Shader = shader; skCanvas.DrawPaint(paint); } } // Draw darker gradient spectrum using (var paint = new SKPaint()) { paint.IsAntialias = true; // Initiate the darkened primary color list var colors = GetGradientOrder(); // create the gradient shader using (var shader = SKShader.CreateLinearGradient( new SKPoint(0, 0), ColorListDirection == ColorListDirection.Horizontal ? new SKPoint(0, skCanvasHeight) : new SKPoint(skCanvasWidth, 0), colors, null, SKShaderTileMode.Clamp)) { paint.Shader = shader; skCanvas.DrawPaint(paint); } } // Picking the Pixel Color values on the Touch Point // Represent the color of the current Touch point SKColor touchPointColor; // Efficient and fast // https://forums.xamarin.com/discussion/92899/read-a-pixel-info-from-a-canvas // create the 1x1 bitmap (auto allocates the pixel buffer) using (SKBitmap bitmap = new SKBitmap(skImageInfo)) { // get the pixel buffer for the bitmap IntPtr dstpixels = bitmap.GetPixels(); // read the surface into the bitmap skSurface.ReadPixels(skImageInfo, dstpixels, skImageInfo.RowBytes, (int)_lastTouchPoint.X, (int)_lastTouchPoint.Y); // access the color touchPointColor = bitmap.GetPixel(0, 0); } // Painting the Touch point using (SKPaint paintTouchPoint = new SKPaint()) { paintTouchPoint.Style = SKPaintStyle.Fill; paintTouchPoint.Color = SKColors.White; paintTouchPoint.IsAntialias = true; var valueToCalcAgainst = (skCanvasWidth > skCanvasHeight) ? skCanvasWidth : skCanvasHeight; var pointerCircleDiameterUnits = PointerCircleDiameterUnits; // 0.6 (Default) pointerCircleDiameterUnits = (float)pointerCircleDiameterUnits / 10f; // calculate 1/10th of that value var pointerCircleDiameter = (float)(valueToCalcAgainst * pointerCircleDiameterUnits); // Outer circle of the Pointer (Ring) skCanvas.DrawCircle( _lastTouchPoint.X, _lastTouchPoint.Y, pointerCircleDiameter / 2, paintTouchPoint); // Draw another circle with picked color paintTouchPoint.Color = touchPointColor; var pointerCircleBorderWidthUnits = PointerCircleBorderUnits; // 0.3 (Default) var pointerCircleBorderWidth = (float)pointerCircleDiameter * (float)pointerCircleBorderWidthUnits; // Calculate against Pointer Circle // Inner circle of the Pointer (Ring) skCanvas.DrawCircle( _lastTouchPoint.X, _lastTouchPoint.Y, ((pointerCircleDiameter - pointerCircleBorderWidth) / 2), paintTouchPoint); } // Set selected color PickedColor = touchPointColor.ToFormsColor(); PickedColorChanged?.Invoke(this, PickedColor); }
private void SkCanvasView_OnPaintSurface(object sender, SKPaintSurfaceEventArgs e) { var skImageInfo = e.Info; var skSurface = e.Surface; var skCanvas = skSurface.Canvas; var skCanvasWidth = skImageInfo.Width; var skCanvasHeight = skImageInfo.Height; skCanvas.Clear(SKColors.White); // Draw gradient rainbow Color spectrum using (var paint = new SKPaint()) { paint.IsAntialias = true; // Initiate the base Color list ColorTypeConverter converter = new ColorTypeConverter(); System.Collections.Generic.List <SKColor> colors = new System.Collections.Generic.List <SKColor>(); foreach (var color in BaseColorList) { colors.Add(((Color)converter.ConvertFromInvariantString(color.ToString())).ToSKColor()); } // create the gradient shader between base Colors using (var shader = SKShader.CreateLinearGradient( new SKPoint(0, 0), ColorFlowDirection == ColorFlowDirection.Horizontal ? new SKPoint(skCanvasWidth, 0) : new SKPoint(0, skCanvasHeight), colors.ToArray(), null, SKShaderTileMode.Clamp)) { paint.Shader = shader; skCanvas.DrawPaint(paint); } } // Draw secondary gradient color spectrum using (var paint = new SKPaint()) { paint.IsAntialias = true; // Initiate gradient color spectrum style layer var colors = GetSecondaryLayerColors(ColorSpectrumStyle); // create the gradient shader between secondary colors using (var shader = SKShader.CreateLinearGradient( new SKPoint(0, 0), ColorFlowDirection == ColorFlowDirection.Horizontal ? new SKPoint(0, skCanvasHeight) : new SKPoint(skCanvasWidth, 0), colors, null, SKShaderTileMode.Clamp)) { paint.Shader = shader; skCanvas.DrawPaint(paint); } } if (!_checkPointerInitPositionDone) { var x = ((float)skCanvasWidth * (float)PointerRingPositionXUnits); var y = ((float)skCanvasHeight * (float)PointerRingPositionYUnits); _lastTouchPoint = new SKPoint(x, y); _checkPointerInitPositionDone = true; } // Picking the Pixel Color values on the Touch Point // Represent the color of the current Touch point SKColor touchPointColor; // Efficient and fast // https://forums.xamarin.com/discussion/92899/read-a-pixel-info-from-a-canvas // create the 1x1 bitmap (auto allocates the pixel buffer) using (SKBitmap bitmap = new SKBitmap(skImageInfo)) { // get the pixel buffer for the bitmap IntPtr dstpixels = bitmap.GetPixels(); // read the surface into the bitmap skSurface.ReadPixels(skImageInfo, dstpixels, skImageInfo.RowBytes, (int)_lastTouchPoint.X, (int)_lastTouchPoint.Y); // access the color touchPointColor = bitmap.GetPixel(0, 0); } // Painting the Touch point using (SKPaint paintTouchPoint = new SKPaint()) { paintTouchPoint.Style = SKPaintStyle.Fill; paintTouchPoint.Color = SKColors.White; paintTouchPoint.IsAntialias = true; var canvasLongestLength = (skCanvasWidth > skCanvasHeight) ? skCanvasWidth : skCanvasHeight; // Calculate 1/10th of the units value for scaling var pointerRingDiameterUnitsScaled = (float)PointerRingDiameterUnits / 10f; // Calculate against Longest Length of Canvas var pointerRingDiameter = (float)canvasLongestLength * pointerRingDiameterUnitsScaled; // Outer circle of the Pointer (Ring) skCanvas.DrawCircle( _lastTouchPoint.X, _lastTouchPoint.Y, (pointerRingDiameter / 2), paintTouchPoint); // Draw another circle with picked color paintTouchPoint.Color = touchPointColor; // Calculate against Pointer Circle var pointerRingInnerCircleDiameter = (float)pointerRingDiameter * (float)PointerRingBorderUnits; // Inner circle of the Pointer (Ring) skCanvas.DrawCircle( _lastTouchPoint.X, _lastTouchPoint.Y, ((pointerRingDiameter - pointerRingInnerCircleDiameter) / 2), paintTouchPoint); } // Set selected color PickedColor = touchPointColor.ToFormsColor(); PickedColorChanged?.Invoke(this, PickedColor); }