public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo) { }
private float GetWidthScaleRatio(SKImageInfo info, SkiaSharp.Extended.Svg.SKSvg svg) { return(info.Width / svg.CanvasSize.Width); }
public static SKPoint Center(SKImageInfo info) { return(new SKPoint((float)info.Width / 2, (float)info.Height / 2)); }
private void PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args) { List <Running.Event> totals = new List <Running.Event>(); totals = EventPage.conn.Table <Event>().ToList(); List <Week> weeks = new List <Week>(); foreach (Running.Event row in totals) { string[] toks = row.ToString().Split(' '); DateTime date = DateTime.Parse(toks[1]); int entryDay = date.Day; int entryWeek = 1; if (entryDay > 7 && entryDay <= 14) { entryWeek = 2; } if (entryDay > 14 && entryDay <= 21) { entryWeek = 3; } if (entryDay > 21 && entryDay <= 28) { entryWeek = 4; } if (entryDay > 28 && entryDay <= 31) { entryWeek = 5; } bool weekExists = false; if (date.Month == MonthsPage.monthClicked && date.Year == YearsPage.yearClicked) { foreach (Week entry in weeks) { if (entry.WeekNum == entryWeek) { weekExists = true; } } if (!weekExists) { Week newWeek = new Week(entryWeek, double.Parse(toks[0])); weeks.Add(newWeek); } else { double newDistance = double.Parse(toks[0]); double oldDistance = weeks.First(d => d.WeekNum == entryWeek).Distance; weeks.First(d => d.WeekNum == entryWeek).Distance = oldDistance + newDistance; } } List <int> distList = new List <int>(); int total = 0; int count = 0; SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; float sep = info.Width * 0.20f; canvas.Clear(); SKPaint paintA = new SKPaint { Style = SKPaintStyle.Fill, Color = Color.Red.ToSKColor(), StrokeWidth = 3 }; SKPaint paintB = new SKPaint { Style = SKPaintStyle.Fill, Color = Color.Blue.ToSKColor(), StrokeWidth = 3 }; foreach (Week item in weeks) { distList.Add((int)item.Distance); total += (int)item.Distance; float percItem = (int)item.Distance / (float)total; float r = Math.Min(info.Width, info.Height) / 2.0f; float barWidth = info.Width * 0.20f; float height = info.Height * percItem; if (count > 0) { sep = sep + 150; } if (count % 2 == 0) { if (count == 0) { canvas.DrawRect(barWidth, height, barWidth, info.Height, paintA); } else { canvas.DrawRect(sep, height, barWidth, info.Height, paintA); } count++; } else { if (count == 0) { canvas.DrawRect(barWidth, height, barWidth, info.Height, paintB); } else { canvas.DrawRect(sep, height - height, barWidth, info.Height, paintB); } count++; } } } }
public static void ReadRGBA16161616F(SKImageInfo imageInfo, BinaryReader r, Span <byte> data) { var bytes = r.ReadBytes(imageInfo.Width * imageInfo.Height * 8); var log = 0d; for (int i = 0, j = 0; i < bytes.Length; i += 8, j += 4) { var hr = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 0)); var hg = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 2)); var hb = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 4)); var lum = (hr * 0.299f) + (hg * 0.587f) + (hb * 0.114f); log += Math.Log(0.0000000001d + lum); } log = Math.Exp(log / (imageInfo.Width * imageInfo.Height)); for (int i = 0, j = 0; i < bytes.Length; i += 8, j += 4) { var hr = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 0)); var hg = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 2)); var hb = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 4)); var ha = HalfTypeHelper.Convert(BitConverter.ToUInt16(bytes, i + 6)); var y = (hr * 0.299f) + (hg * 0.587f) + (hb * 0.114f); var u = (hb - y) * 0.565f; var v = (hr - y) * 0.713f; var mul = 4.0f * y / log; mul = mul / (1.0f + mul); mul /= y; hr = (float)Math.Pow((y + (1.403f * v)) * mul, 2.25f); hg = (float)Math.Pow((y - (0.344f * u) - (0.714f * v)) * mul, 2.25f); hb = (float)Math.Pow((y + (1.770f * u)) * mul, 2.25f); #pragma warning disable SA1503 if (hr < 0) { hr = 0; } if (hr > 1) { hr = 1; } if (hg < 0) { hg = 0; } if (hg > 1) { hg = 1; } if (hb < 0) { hb = 0; } if (hb > 1) { hb = 1; } #pragma warning restore SA1503 data[j + 0] = (byte)(hr * 255); // r data[j + 1] = (byte)(hg * 255); // g data[j + 2] = (byte)(hb * 255); // b data[j + 3] = (byte)(ha * 255); // a } }
private static unsafe bool DrawVideo(Stream videoStream, ThumbnailsRenderContext ctx) { using var formatContext = new FormatContext(videoStream); var stream = formatContext.FindBestVideoStream(); if (stream == null) { return(false); } using var videoStreamDecoder = stream.CreateStreamDecoder(); try { if (videoStreamDecoder.Duration <= 0) { videoStreamDecoder.SeekFrame(10 * 1000000); } if (videoStreamDecoder.Duration > 3) { videoStreamDecoder.SeekFrame(videoStreamDecoder.Duration / 3); } } catch (FFmpegException err) { Console.WriteLine("Seek failed: " + err); } var destinationSize = ThumbnailUtils.ContainSize( new SKSize(videoStreamDecoder.FrameWidth, videoStreamDecoder.FrameHeight), new SKSize(ThumbnailUtils.DefaultMaxWidth * ctx.Density, ThumbnailUtils.DefaultMaxHeight * ctx.Density)).ToSizeI(); var sourcePixelFormat = videoStreamDecoder.PixelFormat; if (!videoStreamDecoder.MoveNext()) { throw new InvalidDataException("Can't decode the video."); } using var vfc = new VideoFrameConverter( videoStreamDecoder.FrameWidth, videoStreamDecoder.FrameHeight, sourcePixelFormat, destinationSize.Width, destinationSize.Height); var convertedFrame = vfc.Convert(videoStreamDecoder.Current.Value); using var colorspace = SKColorSpace.CreateSrgb(); var sourceImageInfo = new SKImageInfo( convertedFrame.width, convertedFrame.height, SKColorType.Rgba8888, SKAlphaType.Unpremul, colorspace); using var image = SKImage.FromPixels(sourceImageInfo, (IntPtr)convertedFrame.data[0], sourceImageInfo.RowBytes); _cachedDecorationImage ??= SKImage.FromEncodedData(ReadDecorationImage()); ThumbnailUtils.DrawShadowView( ctx, new SkImageView(image), _cachedDecorationImage, new SKColor(0, 0, 0), minSize: new SKSize(24, 24)); return(true); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Black, StrokeWidth = 10, StrokeCap = SKStrokeCap.Round, StrokeJoin = SKStrokeJoin.Round }; float widthDensity = Convert.ToSingle(canvasView.CanvasSize.Width / cols); float heightDensity = Convert.ToSingle(canvasView.CanvasSize.Height / rows); canvas.Clear(); SetupCanvas(args); if (drawPath) { Position position = new Position() { X = (int)startingPos.X, Y = (int)startingPos.Y, Direction = RoverDirection.N }; var maxPoints = new List <int>() { rows, cols }; position.ProcessMovements(maxPoints, commands); var actualOutput = $"{position.X} {position.Y} {position.Direction.ToString()}"; outputpath = "Final Pos : " + position.X.ToString() + " " + position.Y.ToString() + " " + position.Direction.ToString(); SKPath path = new SKPath(); path.MoveTo(2 * widthDensity, Convert.ToSingle(canvasView.CanvasSize.Height - (2 * heightDensity))); for (int index = 0; index < position.FlowPath.Count; index++) { path.LineTo((position.FlowPath[index].XPos * widthDensity), Convert.ToSingle(canvasView.CanvasSize.Height - (position.FlowPath[index].YPos * heightDensity))); } canvas.DrawPath(path, paint); SKPaint circlePaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Red, StrokeWidth = 5, StrokeCap = SKStrokeCap.Round, StrokeJoin = SKStrokeJoin.Round }; using (var textPaint = new SKPaint()) { textPaint.TextSize = 30; textPaint.IsAntialias = true; textPaint.Color = SKColors.Red; textPaint.IsStroke = true; textPaint.StrokeWidth = 3; textPaint.TextAlign = SKTextAlign.Center; canvas.DrawText(outputpath, new SKPoint(canvasView.CanvasSize.Width / 2, canvasView.CanvasSize.Height / 2), textPaint); } canvas.DrawCircle(new SKPoint(position.X * widthDensity, canvasView.CanvasSize.Height - position.Y * heightDensity), 15, circlePaint); } }
private void CanvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); SKPoint center = new SKPoint(info.Width / 2, info.Height / 2); float radius = 0.45f * Math.Min(info.Width, info.Height); SKPath path = new SKPath { FillType = SKPathFillType.EvenOdd }; path.MoveTo(info.Width / 2, info.Height / 2 - radius); for (int i = 1; i < 5; i++) { // angle from vertical double angle = i * 4 * Math.PI / 5; path.LineTo(center + new SKPoint(radius * (float)Math.Sin(angle), -radius * (float)Math.Cos(angle))); } path.Close(); SKPaint strokePaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Red, StrokeWidth = 50, StrokeJoin = SKStrokeJoin.Round }; SKPaint fillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.Blue }; canvas.DrawPath(path, fillPaint); canvas.DrawPath(path, strokePaint); SKPaint circlePaint = new SKPaint { StrokeWidth = 10, Color = Color.Red.ToSKColor(), Style = SKPaintStyle.Fill }; SKPath path1 = new SKPath(); path1.FillType = SKPathFillType.EvenOdd; path1.AddCircle(250, 250, 100); path1.AddCircle(350, 250, 100); path1.AddCircle(250, 350, 100); canvas.DrawPath(path1, circlePaint); }
public virtual void DrawInSurface(SKSurface surface, SKImageInfo info) { PaintSurface?.Invoke(this, new SKPaintSurfaceEventArgs(surface, info)); }
public SKPaintSurfaceEventArgs(SKSurface surface, SKImageInfo info) { Surface = surface; Info = info; }
private void CreateFeature() { lock (_sync) { if (Feature == null) { // Create a new one Feature = new Feature { Geometry = Position.ToMapsui(), ["Label"] = Label, }; if (_callout != null) { _callout.Feature.Geometry = Position.ToMapsui(); } } // Check for bitmapId if (_bitmapId != -1) { // There is already a registered bitmap, so delete it BitmapRegistry.Instance.Unregister(_bitmapId); // We don't have any bitmap up to now _bitmapId = -1; } Stream stream = null; switch (Type) { case PinType.Svg: // Load the SVG document if (!string.IsNullOrEmpty(Svg)) { stream = new MemoryStream(Encoding.UTF8.GetBytes(Svg)); } if (stream == null) { return; } _bitmapId = BitmapRegistry.Instance.Register(stream); break; case PinType.Pin: // First we have to create a bitmap from Svg code // Create a new SVG object var svg = new SkiaSharp.Extended.Svg.SKSvg(); // Load the SVG document stream = Utilities.EmbeddedResourceLoader.Load("Images.Pin.svg", typeof(Pin)); if (stream == null) { return; } svg.Load(stream); Width = svg.CanvasSize.Width * Scale; Height = svg.CanvasSize.Height * Scale; // Create bitmap to hold canvas var info = new SKImageInfo((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height) { AlphaType = SKAlphaType.Premul }; var bitmap = new SKBitmap(info); var canvas = new SKCanvas(bitmap); // Now draw Svg image to bitmap using (var paint = new SKPaint() { IsAntialias = true }) { // Replace color while drawing paint.ColorFilter = SKColorFilter.CreateBlendMode(Color.ToSKColor(), SKBlendMode.SrcIn); // use the source color canvas.Clear(); canvas.DrawPicture(svg.Picture, paint); } // Now convert canvas to bitmap using (var image = SKImage.FromBitmap(bitmap)) using (var data = image.Encode(SKEncodedImageFormat.Png, 100)) { _bitmapData = data.ToArray(); } _bitmapId = BitmapRegistry.Instance.Register(new MemoryStream(_bitmapData)); break; case PinType.Icon: if (Icon != null) { using (var image = SKBitmap.Decode(Icon)) { Width = image.Width * Scale; Height = image.Height * Scale; _bitmapId = BitmapRegistry.Instance.Register(new MemoryStream(Icon)); } } break; } // If we have a bitmapId (and we should have one), than draw bitmap, otherwise nothing if (_bitmapId != -1) { // We only want to have one style Feature.Styles.Clear(); Feature.Styles.Add(new SymbolStyle { BitmapId = _bitmapId, SymbolScale = Scale, SymbolRotation = Rotation, SymbolOffset = new Offset(Anchor.X, Anchor.Y), Opacity = 1 - Transparency, Enabled = IsVisible, }); } } }
public void Draw(TetrisField Source, TetrisFieldDrawSkiaParameters parms, IStateOwner pState, SKCanvas g, SKRect Bounds) { Stopwatch sw = new Stopwatch(); sw.Start(); //first how big is each block? float BlockWidth = Bounds.Width / parms.COLCOUNT; float BlockHeight = Bounds.Height / (parms.VISIBLEROWS); //remember, we don't draw the top two rows- we start the drawing at row index 2, skipping 0 and 1 when drawing. lock (Source) { if (parms.FieldBitmap == null || !parms.LastFieldSave.Equals(Bounds) || Source.HasChanged) { Debug.Print("Beginning Field Paint:" + sw.Elapsed.ToString()); SKImageInfo info = new SKImageInfo((int)Bounds.Width, (int)Bounds.Height, SKColorType.Bgra8888); //Note: what we want to do here is actually allocate the field bitmap using a Surface texture. doing it this way paints more slowly, //because it is backed by a bitmap and drawn largely by the CPU. //(nmote using the surface we can retrieve an image snapshot). if (bitmapMode) { using (SKBitmap BuildField = new SKBitmap(info, SKBitmapAllocFlags.None)) { using (SKCanvas gfield = new SKCanvas(BuildField)) { gfield.Clear(SKColors.Transparent); hadAnimated = DrawFieldContents(pState, Source, parms, gfield, Bounds, false); if (parms.FieldBitmap != null) { parms.FieldBitmap.Dispose(); } parms.FieldBitmap = SKImage.FromBitmap(BuildField); } } } else { using (var CreateContext = GRContext.Create(GRBackend.OpenGL, GlobalResources.OpenGLInterface)) { SKCanvas gfield = null; if (FieldSurface == null) { FieldSurface = SKSurface.Create(CreateContext, GlobalResources.CreateRenderTarget((int)Bounds.Width, (int)Bounds.Height), GRSurfaceOrigin.BottomLeft, GlobalResources.DefaultColorType); } var FieldCanvas = FieldSurface.Canvas; FieldCanvas.Flush(); gfield = FieldCanvas; gfield.Clear(SKColors.Transparent); hadAnimated = DrawFieldContents(pState, Source, parms, gfield, Bounds, false); if (parms.FieldBitmap != null) { parms.FieldBitmap.Dispose(); } parms.FieldBitmap = FieldSurface.Snapshot(); } } parms.LastFieldSave = Bounds; Source.HasChanged = false; Debug.Print("Finished Field Paint:" + sw.Elapsed.ToString()); } } Debug.Print("Drawing Field Bitmap" + sw.Elapsed.ToString()); g.DrawImage(parms.FieldBitmap, new SKPoint(0, 0)); //g.DrawBitmap(parms.FieldBitmap,new SKPoint(0,0)); Debug.Print("Field Bitmap finished" + sw.Elapsed.ToString()); if (hadAnimated) { Debug.Print("Animated Field blocks found"); DrawFieldContents(pState, Source, parms, g, Bounds, true); } var activegroups = Source.GetActiveBlockGroups(); Debug.Print("Painting Active Groups:" + sw.Elapsed.ToString()); lock (activegroups) { foreach (Nomino bg in activegroups) { int BaseXPos = bg.X; int BaseYPos = bg.Y; const float RotationTime = 150; double useAngle = 0; TimeSpan tsRotate = DateTime.Now - bg.GetLastRotation(); if (tsRotate.TotalMilliseconds > 0 && tsRotate.TotalMilliseconds < RotationTime) { if (!bg.LastRotateCCW) { useAngle = -90 + ((tsRotate.TotalMilliseconds / RotationTime) * 90); } else { useAngle = 90 - ((tsRotate.TotalMilliseconds / RotationTime) * 90); } } var translation = bg.GetHeightTranslation(pState, BlockHeight); float BlockPercent = translation / BlockHeight; float CalcValue = BlockPercent + (float)bg.Y; if (CalcValue > bg.HighestHeightValue) { bg.HighestHeightValue = CalcValue; } else { translation = (bg.HighestHeightValue - (float)bg.Y) * BlockHeight; } PointF doTranslate = new PointF(0, translation); if (!pState.Settings.std.SmoothFall) { doTranslate = new PointF(0, 0); } //if (Settings.SmoothFall) g.TranslateTransform(doTranslate.X, -BlockHeight + doTranslate.Y); if (pState.Settings.std.SmoothFall) { g.Translate(doTranslate.X, -BlockHeight + doTranslate.Y); } if (useAngle != 0 && pState.Settings.std.SmoothRotate) { int MaxXBlock = (from p in bg select p.X).Max(); int MaxYBlock = (from p in bg select p.Y).Max(); int MinXBlock = (from p in bg select p.X).Min(); int MinYBlock = (from p in bg select p.Y).Min(); int BlocksWidth = MaxXBlock - MinXBlock + 1; int BlocksHeight = MaxYBlock - MinYBlock + 1; PointF UsePosition = new PointF((bg.X + MinXBlock) * BlockWidth, (bg.Y - parms.HIDDENROWS + MinYBlock) * BlockHeight); SizeF tetronimosize = new Size((int)BlockWidth * (BlocksWidth), (int)BlockHeight * (BlocksHeight)); PointF useCenter = new PointF(UsePosition.X + tetronimosize.Width / 2, UsePosition.Y + tetronimosize.Height / 2); g.RotateDegrees((float)useAngle, useCenter.X, useCenter.Y); //g.TranslateTransform(useCenter.X, useCenter.Y); //g.RotateTransform((float)useAngle); //g.TranslateTransform(-useCenter.X, -useCenter.Y); } foreach (NominoElement bge in bg) { int DrawX = BaseXPos + bge.X; int DrawY = BaseYPos + bge.Y - parms.HIDDENROWS; if (DrawX >= 0 && DrawY >= 0 && DrawX < parms.COLCOUNT && DrawY < parms.ROWCOUNT) { float DrawXPx = DrawX * BlockWidth; float DrawYPx = DrawY * BlockHeight; SKRect BlockBounds = new SKRect(DrawXPx, DrawYPx, DrawXPx + BlockWidth, DrawYPx + BlockHeight); TetrisBlockDrawParameters tbd = new TetrisBlockDrawSkiaParameters(g, BlockBounds, bg, pState.Settings); RenderingProvider.Static.DrawElement(pState, g, bge.Block, tbd); } } g.ResetMatrix(); if (!bg.NoGhost) { var GrabGhost = Source.GetGhostDrop(pState, bg, out int dl); if (GrabGhost != null) { foreach (var iterateblock in bg) { float drawGhostX = BlockWidth * (GrabGhost.X + iterateblock.X); float drawGhostY = BlockHeight * (GrabGhost.Y + iterateblock.Y - 2); SKRect BlockBounds = new SKRect(drawGhostX, drawGhostY, drawGhostX + BlockWidth, drawGhostY + BlockHeight); TetrisBlockDrawSkiaParameters tbd = new TetrisBlockDrawSkiaParameters(g, BlockBounds, GrabGhost, pState.Settings); //ImageAttributes Shade = new ImageAttributes(); //SKColorMatrices.GetFader //Shade.SetColorMatrix(ColorMatrices.GetFader(0.5f)); //tbd.ApplyAttributes = Shade; //tbd.OverrideBrush = GhostBrush; tbd.ColorFilter = SKColorMatrices.GetFader(0.5f); var GetHandler = RenderingProvider.Static.GetHandler(typeof(SKCanvas), iterateblock.Block.GetType(), typeof(TetrisBlockDrawSkiaParameters)); GetHandler.Render(pState, tbd.g, iterateblock.Block, tbd); //iterateblock.Block.DrawBlock(tbd); } } } } } Debug.Print("Painting Active Groups Finished:" + sw.Elapsed.ToString()); }
public SKSurface GenerateImage(Color background, int targetWidth = 0, bool borders = false, bool expanded = false, int xShift = 5, int yShift = 5, int colorType = 0) { DateTime time = DateTime.Now; double scalingFactor = 1; int width = shapes.Max(s => s.GetContainer().x2); int heigth = shapes.Max(s => s.GetContainer().y2); if (targetWidth != 0) { // get dimensions of the structure //int x_min = shapes.Min(s => s.GetContainer().x1); //int y_min = shapes.Min(s => s.GetContainer().y1); scalingFactor = Math.Min((double)targetWidth / width, (double)targetWidth / heigth); } var info = new SKImageInfo((int)(width * scalingFactor) + 2 * xShift, (int)(heigth * scalingFactor) + 2 * yShift); SKSurface surf = SKSurface.Create(info); SKCanvas canvas = surf.Canvas; canvas.Clear(new SKColor(background.R, background.G, background.B, background.A)); Parallel.For(0, shapes.Length, (i) => { Color c; if (colorType == 0) { c = colors[shapes[i].Color].mediaColor; } else if (colorType == 1) { c = Color.FromArgb((byte)shapes[i].PrimaryDitherColor.Alpha, (byte)shapes[i].PrimaryDitherColor.Red, (byte)shapes[i].PrimaryDitherColor.Green, (byte)shapes[i].PrimaryDitherColor.Blue); } else { c = Color.FromArgb((byte)shapes[i].PrimaryOriginalColor.Alpha, (byte)shapes[i].PrimaryOriginalColor.Red, (byte)shapes[i].PrimaryOriginalColor.Green, (byte)shapes[i].PrimaryOriginalColor.Blue); } if (shapes[i] is RectangleDomino) { DominoRectangle rect = shapes[i].GetContainer(scalingFactor, expanded); if (c.A != 0) { canvas.DrawRect((float)rect.x + xShift, (float)rect.y + yShift, (float)rect.width, (float)rect.height, new SKPaint() { Color = new SKColor(c.R, c.G, c.B, c.A), IsAntialias = true }); } if (borders) { canvas.DrawRect((float)rect.x + xShift, (float)rect.y + yShift, (float)rect.width, (float)rect.height, new SKPaint() { Color = new SKColor(0, 0, 0, 255), IsAntialias = true, IsStroke = true, StrokeWidth = 1 }); } } else { DominoPath shape = shapes[i].GetPath(scalingFactor); var sdpoints = shape.getSDPath(xShift, yShift); if (sdpoints.Length != 0) { var path = new SKPath(); path.MoveTo(sdpoints[0].X, sdpoints[0].Y); foreach (var line in sdpoints.Skip(0)) { path.LineTo(line.X, line.Y); } path.Close(); if (c.A != 0) { canvas.DrawPath(path, new SKPaint() { Color = new SKColor(c.R, c.G, c.B, c.A), IsAntialias = true, IsStroke = false }); } if (borders) { canvas.DrawPath(path, new SKPaint() { Color = new SKColor(0, 0, 0, 255), IsAntialias = true, IsStroke = true, StrokeWidth = 1 }); } } } }); Debug.WriteLine("Image export took " + (DateTime.Now - time).TotalMilliseconds + "ms"); return(surf); }
private static SKBitmap LoadTga(string file) { SKColorType colorType; using (var image = Pfim.Pfim.FromFile(file)) { var newData = image.Data; var newDataLen = image.DataLen; var stride = image.Stride; switch (image.Format) { case ImageFormat.Rgb8: colorType = SKColorType.Gray8; break; case ImageFormat.R5g6b5: // color channels still need to be swapped colorType = SKColorType.Rgb565; break; case ImageFormat.Rgba16: // color channels still need to be swapped colorType = SKColorType.Argb4444; break; case ImageFormat.Rgb24: // Skia has no 24bit pixels, so we upscale to 32bit var pixels = image.DataLen / 3; newDataLen = pixels * 4; newData = new byte[newDataLen]; for (int i = 0; i < pixels; i++) { newData[i * 4] = image.Data[i * 3]; newData[i * 4 + 1] = image.Data[i * 3 + 1]; newData[i * 4 + 2] = image.Data[i * 3 + 2]; newData[i * 4 + 3] = 255; } stride = image.Width * 4; colorType = SKColorType.Bgra8888; break; case ImageFormat.Rgba32: colorType = SKColorType.Bgra8888; break; default: throw new ArgumentException($"Skia unable to interpret pfim format: {image.Format}"); } var imageInfo = new SKImageInfo(image.Width, image.Height, colorType); var handle = GCHandle.Alloc(newData, GCHandleType.Pinned); var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(newData, 0); using (var data = SKData.Create(ptr, newDataLen, (address, context) => handle.Free())) using (var skImage = SKImage.FromPixelData(imageInfo, data, stride)) { var bitmap = SKBitmap.FromImage(skImage); return(bitmap); } } }
//METHODS /********************************************************************** *********************************************************************/ // do the drawing static void PaintSurface(object sender, SKPaintSurfaceEventArgs e) { info = e.Info; var surfaceWidth = info.Width; var surfaceHeight = info.Height; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; if (canvas != null) { canvas.Clear(); //Important! Otherwise the drawing will look messed up in iOS } /*important: the coordinate system starts in the upper left corner*/ float lborder = canvas.LocalClipBounds.Left; float tborder = canvas.LocalClipBounds.Top; float rborder = canvas.LocalClipBounds.Right; float bborder = canvas.LocalClipBounds.Bottom; xe = rborder / 100; //using the variable surfacewidth instead would mess everything up ye = bborder / 100; MakeSKPaint(); //depends on xe and ye and therfore has to be called after they were initialized /*********************HERE GOES THE DRAWING************************/ //draw background for ram and disc: pink and yellow float bgRamY1 = 1 + rowWidth; float bgRamY2 = bgRamY1 + (rowWidth * ramSize); float bgDiscY1 = bgRamY2; float bgDiscY2 = bgDiscY1 + (rowWidth * discSize); SKRect sk_rBackgroundRam = new SKRect(1 * xe, bgRamY1 * ye, 99 * xe, bgRamY2 * ye); //left , top, right, bottom SKRect sk_rBackgroundDisc = new SKRect(1 * xe, bgDiscY1 * ye, 99 * xe, bgDiscY2 * ye); //left , top, right, bottom canvas.DrawRect(sk_rBackgroundRam, sk_PaintYellow); //left, top, right, bottom, color canvas.DrawRect(sk_rBackgroundDisc, sk_PaintPink); //draw the words RAM and DISC float blackTextSize = sk_blackText.TextSize; float posTexty = (0.5f + rowWidth + (rowWidth / 2.0f)) * ye + (blackTextSize / 2.0f); // ye is already calculated in blacktextsize float posTextx = columnCenter * xe + xe; //its already centered when specified in new SKPaint (... for (int i = 0; i < ramSize; i++) { canvas.DrawText("RAM", posTextx, posTexty, sk_blackText); posTexty += rowWidth * ye; } for (int i = 0; i < discSize; i++) { canvas.DrawText(App._disk, posTextx, posTexty, sk_blackText); posTexty += rowWidth * ye; } //draw the page sequence float blackTextNumbersSize = sk_blackTextNumbers.TextSize; float posTexty2 = ((rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f) - 0.4f * ye; float posTextx2 = (1 + columnCenter + columnWidth) * xe; foreach (var p in SequenceList) { canvas.DrawText(p.ToString(), posTextx2, posTexty2, sk_blackTextNumbers); posTextx2 += columnWidth * xe; } //prepare a square float posPFX1 = 1 + columnWidth; // 1 + columnWidth + (columnWidth / 6) * 1; float posPFX2 = posPFX1 + columnWidth; // posPFX1 + (columnWidth / 6) * 4; float posPFY1 = 1 + rowWidth; //1 + rowWidth + (rowWidth / 10) * 1; float posPFY2 = posPFY1 + rowWidth; // posPFY1 + (rowWidth / 10) * 8; //prepare a circle float radius = 0; float cx = 1 + columnWidth + columnCenter; float cy = 1 + rowWidth + rowCenter; //if (rowWidth > columnWidth){ radius = columnWidth / 2.6f * xe;} //else{ radius = rowWidth / 2.2f * ye;} radius = xPercent(0.025f); //draw pagefails for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { if (PageReplacementStrategies.ram[step, 0, 3] == 2) { //with replacement(circle) canvas.DrawCircle(cx * xe, cy * ye, radius, sk_PaintWhite); //center x, center y, radius, paint canvas.DrawCircle(cx * xe, cy * ye, radius, sk_PaintBlue); //center x, center y, radius, } else if (PageReplacementStrategies.ram[step, 0, 3] == 1) { //without replacement (square) //SKRect sk_Pagefail = new SKRect(posPFX1 * xe, posPFY1 * ye, posPFX2 * xe, posPFY2 * ye); //left , top, right, bottom SKRect sk_Pagefail = new SKRect(posPFX1 * xe, posPFY1 * ye, posPFX2 * xe, posPFY2 * ye); //left , top, right, canvas.DrawRect(sk_Pagefail, sk_PaintWhite); //left, top, right, bottom, color canvas.DrawRect(sk_Pagefail, sk_PaintBlue); //left, top, right, bottom, color } posPFX1 += columnWidth; posPFX2 = posPFX1 + columnWidth;// posPFX1 + (columnWidth / 6) * 4; cx += columnWidth; } //draw Ram: for every step thats done yet, look for pages in ram float posXText = (1 + columnCenter + columnWidth) * xe; float posYText = (rowWidth + (rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f); for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { for (int ram = 0; ram <= PageReplacementStrategies.ram.GetUpperBound(1); ram++) { int page = PageReplacementStrategies.ram[step, ram, 0]; if (page != -1) { canvas.DrawText(page.ToString(), posXText, posYText, sk_blackTextNumbers); } posYText += rowWidth * ye; } posYText = (rowWidth + (rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f); posXText += columnWidth * xe; } //draw Disc: for evry step thats done yet, look for pages in disc posXText = (1 + columnCenter + columnWidth) * xe; posYText += rowWidth * ye; for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { for (int disc = 0; disc <= PageReplacementStrategies.disc.GetUpperBound(1); disc++) { int page = PageReplacementStrategies.disc[step, disc]; if (page != -1) { canvas.DrawText(page.ToString(), posXText, posYText, sk_blackTextNumbers); } posYText += rowWidth * ye; } posYText = (rowWidth * (ramSize + 1) + (rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f); posXText += columnWidth * xe; } //draw M-Bits and R-Bits float posXbit = (1 + columnWidth + columnCenter - columnCenter / 2) * xe; float blackTextSmallSize = sk_blackTextSmall.TextSize; float blankSpace = rowWidth * ye - blackTextSmallSize * 2.000f; if (blankSpace < 0.000f) { blankSpace = 0.000f; } float spaceY = blankSpace / 3.0000f; float posYRbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize; float posYMbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize + spaceY + blackTextSmallSize; if (PageReplacementStrategies.strategy == "RNU FIFO Second Chance" || PageReplacementStrategies.strategy == "RNU FIFO") { for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { for (int ram = 0; ram <= PageReplacementStrategies.ram.GetUpperBound(1); ram++) { if (PageReplacementStrategies.ram[step, ram, 0] != -1) { String rBitValue = PageReplacementStrategies.ram[step, ram, 1].ToString(); String mBitValue = PageReplacementStrategies.ram[step, ram, 2].ToString(); if (PageReplacementStrategies.ram[step, ram, 4] == 0) { canvas.DrawText(rBitValue, posXbit, posYRbit, sk_blackTextSmall); } else { canvas.DrawText(rBitValue, posXbit, posYRbit, sk_redTextSmall); } if (PageReplacementStrategies.ram[step, ram, 5] == 0) { canvas.DrawText(mBitValue, posXbit, posYMbit, sk_blackTextSmall); } else { canvas.DrawText(mBitValue, posXbit, posYMbit, sk_redTextSmall); } } posYMbit += rowWidth * ye; posYRbit += rowWidth * ye; } posXbit += columnWidth * xe; posYMbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize + spaceY + blackTextSmallSize; posYRbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize; } } //Draw rows and colums float posCol = 1; for (int i = 0; i <= colums; i++) { if (i == 0 || i == 1 || i == colums) { //first, second and last line is fat canvas.DrawLine(new SKPoint(posCol * xe, 1 * ye), new SKPoint(posCol * xe, 99 * ye), sk_PaintFat); } else { canvas.DrawLine(new SKPoint(posCol * xe, 1 * ye), new SKPoint(posCol * xe, 99 * ye), sk_PaintThin); } posCol += columnWidth; } float posRow = 1; for (int i = 0; i <= rows; i++) { if (i == 0 || i == 1 || i == rows || i == ramSize + 1) { //first, second and last line is fat, also the seperating line between ram and disc canvas.DrawLine(new SKPoint(1 * xe, posRow * ye), new SKPoint(99 * xe, posRow * ye), sk_PaintFat); } else { canvas.DrawLine(new SKPoint(1 * xe, posRow * ye), new SKPoint(99 * xe, posRow * ye), sk_PaintThin); } posRow += rowWidth; } //execute all drawing actions canvas.Flush(); }
private unsafe SKImage ProjectFisheye(SKPoint centerPoint, float radius, float radians) { var srcInfo = new SKImageInfo(_image.Width, _image.Height, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul); // rows, columns, 4byte color var srcData = new byte[_image.Height, _image.Width, 4]; fixed(byte *ptr = srcData) { if (!_image.ReadPixels(srcInfo, new IntPtr(ptr), _image.Width * 4, 0, 0)) { return(null); } } var dstWidth = (int)Math.Floor(2 * radius); var dstHeight = dstWidth / 2; var rows = dstHeight; var columns = dstWidth; // rows, columns, 4byte color var dstData = new byte[rows, columns, 4]; for (var row = 0; row < rows; row++) { for (var column = 0; column < columns; column++) { // normalize x, y to equirectangular space var dstWidthHalf = dstWidth / 2.0; var dstHeightHalf = dstHeight / 2.0; var equirectX = -1 * (column - dstWidthHalf) / dstWidthHalf; var equirectY = -1 * (row - dstHeightHalf) / dstHeightHalf; // long/lat var longitude = equirectX * Math.PI; var latitude = equirectY * Math.PI / 2; // 3D projection var pX = Math.Cos(latitude) * Math.Cos(longitude); var pY = Math.Cos(latitude) * Math.Sin(longitude); var pZ = Math.Sin(latitude); // fish eye normalized coords var r = 2 * Math.Atan2(Math.Sqrt(Math.Pow(pX, 2) + Math.Pow(pZ, 2)), pY) / (202 * Math.PI / 180); // 202 degrees aperture for ricoh theta s var theta = Math.Atan2(pZ, pX); var unitCirclePoint = new SKPoint((float)(r * Math.Cos(theta)), (float)(r * Math.Sin(theta))); if (Math.Abs(unitCirclePoint.X) > 1 || Math.Abs(unitCirclePoint.Y) > 1) { continue; } // compensate for rotation of fish eye var matrix = SKMatrix.MakeRotation(radians); unitCirclePoint = matrix.MapPoint(unitCirclePoint); // fisheye normalized coords to src image space. var srcX = (int)Math.Floor(centerPoint.X + unitCirclePoint.X * radius); var srcY = (int)Math.Floor(centerPoint.Y - unitCirclePoint.Y * radius); // clamp to image bounds if (srcX < 0 || srcX >= _image.Width || srcY < 0 || srcY >= _image.Height) { continue; } // y, x flipped cause doing row column var b = srcData[srcY, srcX, 0]; var g = srcData[srcY, srcX, 1]; var red = srcData[srcY, srcX, 2]; var a = srcData[srcY, srcX, 3]; dstData[row, column, 0] = b; dstData[row, column, 1] = g; dstData[row, column, 2] = red; dstData[row, column, 3] = a; } } var surface = SKSurface.Create(new SKImageInfo(dstWidth, dstHeight)); surface.Canvas.Clear(SKColors.DarkSlateGray); var dstBitmap = new SKBitmap(dstWidth, dstHeight); fixed(byte *ptr = dstData) { dstBitmap.SetPixels((IntPtr)ptr); } surface.Canvas.DrawBitmap(dstBitmap, 0, 0); return(surface.Snapshot()); }
static void CreateThumbnail(string[] args) { // Parse args if (args.Length < 1) { Console.WriteLine( "Usage: {0} <Config-File>", Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) ); return; } string configFile = args[0]; if (!configFile.ToLower().EndsWith(".config")) { configFile = Path.Combine("res", "Config", $"{configFile}.config"); } // Load in the requested config file var config = new Config(configFile); // Load the background image if (!config.Required("the background image", out string backgroundImage, "background")) { return; } using (var background = Helpers.LoadImage(backgroundImage.ToOS())) { // Create a surface of matching size var info = new SKImageInfo(background.Width, background.Height, Helpers.RGBA); using (var surface = SKSurface.Create(info)) { // Clear the canvas var canvas = surface.Canvas; canvas.Clear(new SKColor(0, 0, 0, 0)); // Draw the background canvas.DrawImage(background, 0.0f, 0.0f); // Determine the center-line if (!config.Required("the center line's vertical position", out string configCenterLine, "centerline")) { return; } float centerLine = configCenterLine.ParseAsDistance(info.Height); // Read padding from config if (!config.Required("the padding on left/right", out string configPaddingHorizontal, "padding", "horizontal")) { return; } float paddingHorizontal = configPaddingHorizontal.ParseAsDistance(info.Width); if (!config.Required("the padding below the logo", out string configPaddingLogoBottom, "padding", "logo.bottom")) { return; } float paddingLogoBottom = configPaddingLogoBottom.ParseAsDistance(info.Height); if (!config.Required("the padding above the text", out string configPaddingTextTop, "padding", "text.top")) { return; } float paddingTextTop = configPaddingTextTop.ParseAsDistance(info.Height); if (!config.Required("the padding on top/bottom", out string configPaddingVertical, "padding", "vertical")) { return; } float paddingVertical = configPaddingVertical.ParseAsDistance(info.Height); // Draw the game logo if (!config.Required("the game logo", out string logoImage, "logo")) { return; } if (!logoImage.ToLower().EndsWith(".png")) { logoImage = $"res/Logos/{logoImage}.png"; } using (var logo = Helpers.LoadImage(logoImage.ToOS())) { // Calculate the scale for the logo var bottomCenter = new SKPoint(info.Width * 0.5f, centerLine - paddingLogoBottom); float logoScale = Math.Min( (bottomCenter.X - paddingHorizontal) / logo.Width * 2.0f, (bottomCenter.Y - paddingVertical) / logo.Height ); // Draw the logo canvas.DrawImage(logo, new SKRect( bottomCenter.X - logoScale * logo.Width * 0.5f, bottomCenter.Y - logoScale * logo.Height, bottomCenter.X + logoScale * logo.Width * 0.5f, bottomCenter.Y )); } // Parse the font configuration if (!config.Required("if the font displays in all caps", out string configAllCaps, "text", "all.caps")) { return; } bool allCaps = configAllCaps.Equals("true", StringComparison.CurrentCultureIgnoreCase); if (!config.Required("the font", out string fontFile, "text", "font")) { return; } if (!fontFile.ToLower().EndsWith(".ttf")) { fontFile = $"res/Fonts/{fontFile}/{fontFile}.ttf"; } if (!config.Required("the maximum font size", out string configFontSize, "text", "size")) { return; } if (!configFontSize.EndsWith("px")) { Console.WriteLine("The font size must be in pixels"); return; } float fontSize = float.Parse(configFontSize.Substring(0, configFontSize.Length - 2)); // Get the video title and episode if (!config.Required("the video's episode", out string configEpisode, "video", "episode")) { return; } int episode = int.Parse(configEpisode); if (!config.Required("the video's title", out string title, "video", "title")) { return; } string content = $"#{episode} {title}"; // Draw some text at the center using (var minecrafter3 = Helpers.LoadFont(fontFile.ToOS())) { // Determine the scale for the text var paint = new SKPaint { Color = new SKColor(255, 255, 255, 255), IsAntialias = false, Style = SKPaintStyle.Fill, TextSize = fontSize, Typeface = minecrafter3 }; var topCenter = new SKPoint(info.Width * 0.5f, centerLine + paddingTextTop); var size = paint.MeasureTextExt(content, allCaps); paint.TextSize *= Math.Min(1.0f, Math.Min( (topCenter.X - paddingHorizontal) / size.Width * 2.0f, (info.Height - topCenter.Y - paddingVertical) / size.Height )); // Draw the text canvas.DrawTextExt( content, topCenter.X, topCenter.Y, paint, HAlign.Center, VAlign.Top, allCaps ); } // Diagnostic marker if (config.TryGet(out string configRenderCenter, "rendering", "center") && configRenderCenter.Equals("true", StringComparison.CurrentCultureIgnoreCase)) { canvas.DrawCircle( info.Width * 0.5f, centerLine, 25.0f, new SKPaint { Color = new SKColor(255, 0, 0, 255), IsAntialias = false, Style = SKPaintStyle.Fill } ); } // Save to a file if (!config.Required("the output directory", out string configOutputDir, "video", "output.directory")) { return; } string outputDir = Path.GetFullPath(configOutputDir.ToOS()); if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } surface.SaveToFile(Path.Combine(outputDir, $"Episode_{episode.ToString("D3")}.png")); } } }
private SKData GetImageData(string imagePath, ResizeParams resizeParams, DateTime lastWriteTimeUtc) { // check cache and return if cached long cacheKey; unchecked { cacheKey = imagePath.GetHashCode() + lastWriteTimeUtc.ToBinary() + resizeParams.ToString().GetHashCode(); } SKData imageData; byte[] imageBytes; bool isCached = _memoryCache.TryGetValue <byte[]>(cacheKey, out imageBytes); if (isCached) { _logger.LogInformation("Serving from cache"); return(SKData.CreateCopy(imageBytes)); } SKCodecOrigin origin; // this represents the EXIF orientation var bitmap = LoadBitmap(File.OpenRead(imagePath), out origin); // always load as 32bit (to overcome issues with indexed color) // if autorotate = true, and origin isn't correct for the rotation, rotate it if (resizeParams.autorotate && origin != SKCodecOrigin.TopLeft) { bitmap = RotateAndFlip(bitmap, origin); } // if either w or h is 0, set it based on ratio of original image if (resizeParams.h == 0) { resizeParams.h = (int)Math.Round(bitmap.Height * (float)resizeParams.w / bitmap.Width); } else if (resizeParams.w == 0) { resizeParams.w = (int)Math.Round(bitmap.Width * (float)resizeParams.h / bitmap.Height); } // if we need to crop, crop the original before resizing if (resizeParams.mode == "crop") { bitmap = Crop(bitmap, resizeParams); } // store padded height and width var paddedHeight = resizeParams.h; var paddedWidth = resizeParams.w; // if we need to pad, or max, set the height or width according to ratio if (resizeParams.mode == "pad" || resizeParams.mode == "max") { var bitmapRatio = (float)bitmap.Width / bitmap.Height; var resizeRatio = (float)resizeParams.w / resizeParams.h; if (bitmapRatio > resizeRatio) // original is more "landscape" { resizeParams.h = (int)Math.Round(bitmap.Height * ((float)resizeParams.w / bitmap.Width)); } else { resizeParams.w = (int)Math.Round(bitmap.Width * ((float)resizeParams.h / bitmap.Height)); } } // resize var resizedImageInfo = new SKImageInfo(resizeParams.w, resizeParams.h, SKImageInfo.PlatformColorType, bitmap.AlphaType); var resizedBitmap = bitmap.Resize(resizedImageInfo, SKBitmapResizeMethod.Lanczos3); // optionally pad if (resizeParams.mode == "pad") { resizedBitmap = Pad(resizedBitmap, paddedWidth, paddedHeight, resizeParams.format != "png"); } // encode var resizedImage = SKImage.FromBitmap(resizedBitmap); var encodeFormat = resizeParams.format == "png" ? SKEncodedImageFormat.Png : SKEncodedImageFormat.Jpeg; imageData = resizedImage.Encode(encodeFormat, resizeParams.quality); // cache the result _memoryCache.Set <byte[]>(cacheKey, imageData.ToArray()); // cleanup resizedImage.Dispose(); bitmap.Dispose(); resizedBitmap.Dispose(); return(imageData); }
public MapInfo GetMapInfo(double x, double y, IReadOnlyViewport viewport, IEnumerable <ILayer> layers, int margin = 0) { // todo: use margin to increase the pixel area // todo: We will need to select on style instead of layer layers = layers .Select(l => (l is RasterizingLayer rl) ? rl.ChildLayer : l) .Where(l => l.IsMapInfoLayer); var list = new List <MapInfoRecord>(); var result = new MapInfo() { ScreenPosition = new Point(x, y), WorldPosition = viewport.ScreenToWorld(x, y), Resolution = viewport.Resolution }; if (!viewport.Extent.Contains(viewport.ScreenToWorld(result.ScreenPosition))) { return(result); } try { var width = (int)viewport.Width; var height = (int)viewport.Height; var imageInfo = new SKImageInfo(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul); var intX = (int)x; var intY = (int)y; using (var surface = SKSurface.Create(imageInfo)) { if (surface == null) { return(null); } surface.Canvas.ClipRect(new SKRect((float)(x - 1), (float)(y - 1), (float)(x + 1), (float)(y + 1))); surface.Canvas.Clear(SKColors.Transparent); var pixmap = surface.PeekPixels(); var color = pixmap.GetPixelColor(intX, intY); VisibleFeatureIterator.IterateLayers(viewport, layers, (v, layer, style, feature, opacity) => { surface.Canvas.Save(); // 1) Clear the entire bitmap surface.Canvas.Clear(SKColors.Transparent); // 2) Render the feature to the clean canvas RenderFeature(surface.Canvas, v, layer, style, feature, opacity); // 3) Check if the pixel has changed. if (color != pixmap.GetPixelColor(intX, intY)) { // 4) Add feature and style to result list.Add(new MapInfoRecord(feature, style, layer)); } surface.Canvas.Restore(); }); } if (list.Count == 0) { return(result); } list.Reverse(); var itemDrawnOnTop = list.First(); result.Feature = itemDrawnOnTop.Feature; result.Style = itemDrawnOnTop.Style; result.Layer = itemDrawnOnTop.Layer; result.MapInfoRecords = list; } catch (Exception exception) { Logger.Log(LogLevel.Error, "Unexpected error in skia renderer", exception); } return(result); }
private void PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args) { List <Running.Event> totals = new List <Running.Event>(); totals = EventPage.conn.Table <Event>().ToList(); months = new List <Month>(); foreach (Running.Event row in totals) { string[] toks = row.ToString().Split(' '); DateTime date = DateTime.Parse(toks[1]); int entryMonth = date.Month; int entryYear = date.Year; bool monthExists = false; if (date.Year == YearsPage.yearClicked) { foreach (Month entry in months) { if (entry.MonthNum == entryMonth) { monthExists = true; } } if (!monthExists) { Month newMonth = new Month(entryMonth, double.Parse(toks[0])); months.Add(newMonth); } else { double newDistance = double.Parse(toks[0]); double oldDistance = months.First(d => d.MonthNum == entryMonth).Distance; months.First(d => d.MonthNum == entryMonth).Distance = oldDistance + newDistance; } } List <int> distList = new List <int>(); int total = 0; int count = 0; SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; float sep = info.Width * 0.20f; canvas.Clear(); SKPaint paintA = new SKPaint { Style = SKPaintStyle.Fill, Color = Color.Red.ToSKColor(), StrokeWidth = 3 }; SKPaint paintB = new SKPaint { Style = SKPaintStyle.Fill, Color = Color.Blue.ToSKColor(), StrokeWidth = 3 }; foreach (Month item in months) { distList.Add((int)item.Distance); total += (int)item.Distance; float percItem = (int)item.Distance / (float)total; float r = Math.Min(info.Width, info.Height) / 2.0f; float barWidth = info.Width * 0.20f; float height = info.Height * percItem; if (count > 0) { sep = sep + 150; } if (count % 2 == 0) { if (count == 0) { canvas.DrawRect(barWidth, height, barWidth, info.Height, paintA); } else { canvas.DrawRect(sep, height, barWidth, info.Height, paintA); } count++; } else { if (count == 0) { canvas.DrawRect(barWidth, height, barWidth, info.Height, paintB); } else { canvas.DrawRect(sep, height - height, barWidth, info.Height, paintB); } count++; } } } }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); // Assume both bitmaps are square for display rectangle float size = Math.Min(info.Width, info.Height); SKRect rect = SKRect.Create(size, size); float x = (info.Width - size) / 2; float y = (info.Height - size) / 2; rect.Offset(x, y); using (SKPaint paint0 = new SKPaint()) using (SKPaint paint1 = new SKPaint()) using (SKPaint paint2 = new SKPaint()) { SKColor[] colors = new SKColor[] { SKColors.Black, SKColors.Transparent }; float progress = (float)progressSlider.Value; float[] positions = new float[] { 1.1f * progress - 0.1f, 1.1f * progress }; switch ((TransitionMode)transitionPicker.SelectedIndex) { case TransitionMode.Linear: paint0.Shader = SKShader.CreateLinearGradient( new SKPoint(rect.Left, 0), new SKPoint(rect.Right, 0), colors, positions, SKShaderTileMode.Clamp); break; case TransitionMode.Radial: paint0.Shader = SKShader.CreateRadialGradient( new SKPoint(rect.MidX, rect.MidY), (float)Math.Sqrt(Math.Pow(rect.Width / 2, 2) + Math.Pow(rect.Height / 2, 2)), colors, positions, SKShaderTileMode.Clamp); break; case TransitionMode.Sweep: paint0.Shader = SKShader.CreateSweepGradient( new SKPoint(rect.MidX, rect.MidY), colors, positions); break; } canvas.DrawRect(rect, paint0); paint1.BlendMode = SKBlendMode.SrcOut; canvas.DrawBitmap(bitmap1, rect, paint1); paint2.BlendMode = SKBlendMode.DstOver; canvas.DrawBitmap(bitmap2, rect, paint2); } }
/// <summary> /// Initializes a new instance of the <see cref="AvaloniaDrawingContext"/> class. /// </summary> /// <param name="info">The information.</param> /// <param name="surface">The surface.</param> /// <param name="canvas">The canvas.</param> public AvaloniaDrawingContext(SKImageInfo info, SKSurface surface, SKCanvas canvas) : base(info, surface, canvas) { }
public virtual void DrawInSurface(SKSurface surface, SKImageInfo info) { }
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath renderBounds, SKPaint paint) { }
public static SKBitmap ResizeImage(SKBitmap original, int w, int h, string mode) { SKBitmap bitmap = null; if (w == 0 && h != 0) { w = original.Width * h / original.Height; var imageInfo = new SKImageInfo(w, h, SKImageInfo.PlatformColorType, original.AlphaType); bitmap = original.Resize(imageInfo, SKFilterQuality.High); } else if (h == 0 && w != 0) { h = original.Height * w / original.Width; var imageInfo = new SKImageInfo(w, h, SKImageInfo.PlatformColorType, original.AlphaType); bitmap = original.Resize(imageInfo, SKFilterQuality.High); } else if (w != 0 && h != 0) { float originalRatio = ((float)original.Height) / ((float)original.Width); float ratio = ((float)h) / ((float)w); switch (mode) { case "pad": { SKRectI drawRect; if (originalRatio < ratio) { var newW = w; var newH = original.Height * w / original.Width; var pad = (h - newH) / 2; drawRect = new SKRectI { Left = 0, Top = pad, Right = newW, Bottom = newH + pad }; } else { var newW = original.Width * h / original.Height; var newH = h; var pad = (w - newW) / 2; drawRect = new SKRectI { Left = pad, Top = 0, Right = newW + pad, Bottom = newH }; } bitmap = new SKBitmap(w, h, true); var canvas = new SKCanvas(bitmap); canvas.Clear(new SKColor(255, 255, 255)); var imageInfo = new SKImageInfo(drawRect.Width, drawRect.Height, SKImageInfo.PlatformColorType, original.AlphaType); original = original.Resize(imageInfo, SKFilterQuality.High); canvas.DrawBitmap(original, drawRect, new SKPaint()); canvas.Flush(); canvas.Dispose(); break; } case "crop": { SKRectI drawRect; if (originalRatio < ratio) { var newW = original.Width * h / original.Height; var pad = (newW - w) / 2; var imageInfo = new SKImageInfo(newW, h, SKImageInfo.PlatformColorType, original.AlphaType); var resizedBitmap = original.Resize(imageInfo, SKFilterQuality.High); drawRect = new SKRectI { Left = pad, Top = 0, Right = w + pad, Bottom = h }; bitmap = new SKBitmap(drawRect.Width, drawRect.Height, true); resizedBitmap.ExtractSubset(bitmap, drawRect); } else { var newH = original.Height * w / original.Width; var pad = (newH - h) / 2; var imageInfo = new SKImageInfo(w, newH, SKImageInfo.PlatformColorType, original.AlphaType); var resizedBitmap = original.Resize(imageInfo, SKFilterQuality.High); drawRect = new SKRectI { Left = 0, Top = pad, Right = w, Bottom = h + pad }; bitmap = new SKBitmap(drawRect.Width, drawRect.Height); resizedBitmap.ExtractSubset(bitmap, drawRect); } break; } default: break; } } else { bitmap = original.Copy(); } original.Dispose(); return(bitmap); }
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath renderBounds, SKPaint paint) { paint.ImageFilter = SKImageFilter.CreateColorFilter(SKColorFilter.CreateColorMatrix(Properties.ColorMatrix.CurrentValue), paint.ImageFilter); }
private float GetHeightScaleRatio(SKImageInfo info, SkiaSharp.Extended.Svg.SKSvg svg) { return(info.Height / svg.CanvasSize.Height); }
private void SKCanvasView_PaintSurface_2(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); float[] borderDot = new float[] { 5, 5 }; SKPaint paint = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.White, StrokeWidth = 1, PathEffect = SKPathEffect.CreateDash(borderDot, 10) }; Assembly assembly = GetType().GetTypeInfo().Assembly; if ((SKCanvasView)sender == Center) { string resourceID = "LoginPageDesign.images.mainImage.png"; using (Stream stream = assembly.GetManifestResourceStream(resourceID)) { var resourceBitmap = SKBitmap.Decode(stream); if (resourceBitmap != null) { canvas.DrawCircle(0.42f * info.Width, 0.5f * info.Height, 110, paint); canvas.DrawBitmap(resourceBitmap, ((0.42f * info.Width) - 110), (0.5f * info.Height) - 110); } } } if ((SKCanvasView)sender == Right) { string resourceID = "LoginPageDesign.images.grocery.png"; using (Stream stream = assembly.GetManifestResourceStream(resourceID)) { var resourceBitmap = SKBitmap.Decode(stream); if (resourceBitmap != null) { canvas.DrawCircle((0.42f * info.Width) + 110, 0.5f * info.Height, 20, paint); canvas.DrawBitmap(resourceBitmap, ((0.42f * info.Width) + 110) - 10, (0.5f * info.Height) - 10); } } } if ((SKCanvasView)sender == Left) { string resourceID = "LoginPageDesign.images.location.png"; using (Stream stream = assembly.GetManifestResourceStream(resourceID)) { var resourceBitmap = SKBitmap.Decode(stream); if (resourceBitmap != null) { canvas.DrawCircle((0.42f * info.Width) - 110, 0.5f * info.Height, 20, paint); canvas.DrawBitmap(resourceBitmap, ((0.42f * info.Width) - 110) - 10, (0.5f * info.Height) - 10); } } } if ((SKCanvasView)sender == Top) { string resourceID = "LoginPageDesign.images.phone.png"; using (Stream stream = assembly.GetManifestResourceStream(resourceID)) { var resourceBitmap = SKBitmap.Decode(stream); if (resourceBitmap != null) { canvas.DrawCircle(0.42f * info.Width, (0.5f * info.Height) - 110, 20, paint); canvas.DrawBitmap(resourceBitmap, (0.42f * info.Width) - 10, ((0.5f * info.Height) - 110) - 10); } } } if ((SKCanvasView)sender == Bottom) { string resourceID = "LoginPageDesign.images.restaurant.png"; using (Stream stream = assembly.GetManifestResourceStream(resourceID)) { var resourceBitmap = SKBitmap.Decode(stream); if (resourceBitmap != null) { canvas.DrawCircle(0.42f * info.Width, (0.5f * info.Height) + 110, 20, paint); canvas.DrawBitmap(resourceBitmap, (0.42f * info.Width) - 10, ((0.5f * info.Height) + 110) - 10); } } } }
public async Task drawGaugeAsync() { // Radial Gauge Constants int uPadding = 150; int side = 500; int radialGaugeWidth = 55; // Line TextSize inside Radial Gauge int lineSize1 = 220; int lineSize2 = 70; int lineSize3 = 80; int lineSize4 = 100; // Line Y Coordinate inside Radial Gauge int lineHeight1 = 70; int lineHeight2 = 170; int lineHeight3 = 270; int lineHeight4 = 370; int lineHeight5 = 530; // Start & End Angle for Radial Gauge float startAngle = -220; float sweepAngle = 260; try { // Getting Canvas Info SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; progressUtils.setDevice(info.Height, info.Width); canvas.Clear(); SKBlendMode blend = SKBlendMode.SrcIn; canvas.DrawColor(Color.White.ToSKColor(), blend); // Getting Device Specific Screen Values // ------------------------------------------------- // Top Padding for Radial Gauge float upperPading = progressUtils.getFactoredHeight(uPadding); /* Coordinate Plotting for Radial Gauge * * (X1,Y1) ------------ * | (XC,YC) | * | . | * Y | | * | | * ------------ (X2,Y2)) * X * * To fit a perfect Circle inside --> X==Y * i.e It should be a Square */ // Xc & Yc are center of the Circle int Xc = info.Width / 2; float Yc = progressUtils.getFactoredHeight(side); // X1 Y1 are lefttop cordiates of rectange int X1 = (int)(Xc - Yc); int Y1 = (int)(Yc - Yc + upperPading); // X2 Y2 are rightbottom cordiates of rectange int X2 = (int)(Xc + Yc); int Y2 = (int)(Yc + Yc + upperPading); //Loggig Screen Specific Calculated Values Debug.WriteLine("INFO " + info.Width + " - " + info.Height); Debug.WriteLine(" C : " + upperPading + " " + info.Height); Debug.WriteLine(" C : " + Xc + " " + Yc); Debug.WriteLine("XY : " + X1 + " " + Y1); Debug.WriteLine("XY : " + X2 + " " + Y2); // Empty Gauge Styling SKPaint paint1 = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.FromHex("#e0dfdf").ToSKColor(), // Colour of Radial Gauge StrokeWidth = progressUtils.getFactoredWidth(radialGaugeWidth), // Width of Radial Gauge StrokeCap = SKStrokeCap.Round // Round Corners for Radial Gauge }; // Filled Gauge Styling SKPaint paint2 = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.FromHex("#05c782").ToSKColor(), // Overlay Colour of Radial Gauge StrokeWidth = progressUtils.getFactoredWidth(radialGaugeWidth), // Overlay Width of Radial Gauge StrokeCap = SKStrokeCap.Round // Round Corners for Radial Gauge }; // Defining boundaries for Gauge SKRect rect = new SKRect(X1, Y1, X2, Y2); //canvas.DrawRect(rect, paint1); //canvas.DrawOval(rect, paint1); // Rendering Empty Gauge SKPath path1 = new SKPath(); path1.AddArc(rect, startAngle, sweepAngle); canvas.DrawPath(path1, paint1); // Rendering Filled Gauge SKPath path2 = new SKPath(); path2.AddArc(rect, startAngle, (float)sweepAngleSlider.Value); canvas.DrawPath(path2, paint2); //---------------- Drawing Text Over Gauge --------------------------- // Achieved Minutes using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#676a69"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressUtils.getFactoredHeight(lineSize1); skPaint.Typeface = SKTypeface.FromFamilyName( "Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); // Drawing Achieved Minutes Over Radial Gauge // if (sw_listToggle.IsToggled) // canvas.DrawText(chartvalue + "", Xc, Yc + progressUtils.getFactoredHeight(lineHeight1), skPaint); // else // canvas.DrawText(dailyWorkout + "", Xc, Yc + progressUtils.getFactoredHeight(lineHeight1), skPaint); } // Achieved Minutes Text Styling using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#676a69"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressUtils.getFactoredHeight(lineSize2); // canvas.DrawText("Seconds", Xc, Yc + progressUtils.getFactoredHeight(lineHeight2), skPaint); } // Goal Minutes Text Styling using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#e2797a"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressUtils.getFactoredHeight(lineSize3); skPaint.Typeface = SKTypeface.FromFamilyName( "Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); // Drawing Text Over Radial Gauge // if (sw_listToggle.IsToggled) // canvas.DrawText(DateTime.Now.ToString("dddd, dd'-'MM'-'yyyy"), Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint); //else { // canvas.DrawText("Goal " + goal / 30 + " Min", Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint); } } // Goal Minutes Text Styling using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#e2797a"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressUtils.getFactoredHeight(lineSize3); skPaint.Typeface = SKTypeface.FromFamilyName( "Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); // Drawing Text Over Radial Gauge // if (sw_listToggle.IsToggled) // canvas.DrawText(DateTime.Now.ToString("HH:mm:ss"), Xc, Yc + progressUtils.getFactoredHeight(lineHeight4), skPaint); //else { // canvas.DrawText("Goal " + goal / 30 + " Min", Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint); } } // Goal Minutes Text Styling using (SKPaint skPaint = new SKPaint()) { skPaint.Style = SKPaintStyle.Fill; skPaint.IsAntialias = true; skPaint.Color = SKColor.Parse("#676a69"); skPaint.TextAlign = SKTextAlign.Center; skPaint.TextSize = progressUtils.getFactoredHeight(lineSize4); skPaint.Typeface = SKTypeface.FromFamilyName( "Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); // Drawing Text Over Radial Gauge // if (sw_listToggle.IsToggled) canvas.DrawText("Battery " + Chartvalue + "%", Xc, Yc + progressUtils.getFactoredHeight(lineHeight5), skPaint); //else { // canvas.DrawText("Goal " + goal / 30 + " Min", Xc, Yc + progressUtils.getFactoredHeight(lineHeight3), skPaint); } } } catch (Exception e) { Debug.WriteLine(e.StackTrace); } }
private void canvas_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; SKPaint strokePaint = GetPaintColor(SKPaintStyle.Stroke, null, 10, SKStrokeCap.Square); SKPaint dotPaint = GetPaintColor(SKPaintStyle.Fill, "#DE0469"); SKPaint hrPaint = GetPaintColor(SKPaintStyle.Stroke, "#262626", 4, SKStrokeCap.Square); SKPaint minPaint = GetPaintColor(SKPaintStyle.Stroke, "#DE0469", 2, SKStrokeCap.Square); SKPaint bgPaint = GetPaintColor(SKPaintStyle.Fill, "#FFFFFF"); canvas.Clear(); SKRect arcRect = new SKRect(10, 10, info.Width - 10, info.Height - 10); SKRect bgRect = new SKRect(25, 25, info.Width - 25, info.Height - 25); canvas.DrawOval(bgRect, bgPaint); strokePaint.Shader = SKShader.CreateLinearGradient( new SKPoint(arcRect.Left, arcRect.Top), new SKPoint(arcRect.Right, arcRect.Bottom), new SKColor[] { SKColor.Parse("#DE0469"), SKColors.Transparent }, new float[] { 0, 1 }, SKShaderTileMode.Repeat); path.ArcTo(arcRect, 45, arcLength, true); canvas.DrawPath(path, strokePaint); canvas.Translate(info.Width / 2, info.Height / 2); canvas.Scale(info.Width / 200f); canvas.Save(); canvas.RotateDegrees(240); canvas.DrawCircle(0, -75, 2, dotPaint); canvas.Restore(); DateTime dateTime = DateTime.Now; //Draw hour hand canvas.Save(); canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f); canvas.DrawLine(0, 5, 0, -60, hrPaint); canvas.Restore(); //Draw minute hand canvas.Save(); canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f); canvas.DrawLine(0, 10, 0, -90, minPaint); canvas.Restore(); canvas.DrawCircle(0, 0, 5, dotPaint); secondsTxt.Text = dateTime.Second.ToString("00"); timeTxt.Text = dateTime.ToString("hh:mm"); periodTxt.Text = dateTime.Hour >= 12 ? "PM" : "AM"; var alarmDiff = alarmDate - dateTime; alarmTxt.Text = $"{alarmDiff.Hours}h {alarmDiff.Minutes}m until next alarm"; }