/// <summary> /// Draws grid lines to match boundaries for 10 character PlusCodes. /// </summary> /// <param name="totalArea">the GeoArea to draw lines in</param> /// <returns>the byte array for the maptile png file</returns> public byte[] DrawCell10GridLines(GeoArea totalArea) { int imageSizeX = IMapTiles.SlippyTileSizeSquare; int imageSizeY = IMapTiles.SlippyTileSizeSquare; SKBitmap bitmap = new SKBitmap(imageSizeX, imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul); SKCanvas canvas = new SKCanvas(bitmap); var bgColor = new SKColor(); SKColor.TryParse("00000000", out bgColor); canvas.Clear(bgColor); canvas.Scale(1, -1, imageSizeX / 2, imageSizeY / 2); SKPaint paint = new SKPaint(); SKColor color = new SKColor(); SKColor.TryParse("#00CCFF", out color); paint.Color = color; paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 1; paint.IsAntialias = true; double degreesPerPixelX = totalArea.LongitudeWidth / imageSizeX; double degreesPerPixelY = totalArea.LatitudeHeight / imageSizeY; //This is hardcoded to Cell 8 spaced gridlines. var imageLeft = totalArea.WestLongitude; var spaceToFirstLineLeft = (imageLeft % resolutionCell10); var imageBottom = totalArea.SouthLatitude; var spaceToFirstLineBottom = (imageBottom % resolutionCell10); double lonLineTrackerDegrees = imageLeft - spaceToFirstLineLeft; //This is degree coords while (lonLineTrackerDegrees <= totalArea.EastLongitude + resolutionCell10) //This means we should always draw at least 2 lines, even if they're off-canvas. { var geoLine = new LineString(new Coordinate[] { new Coordinate(lonLineTrackerDegrees, 90), new Coordinate(lonLineTrackerDegrees, -90) }); var points = PolygonToSKPoints(geoLine, totalArea, degreesPerPixelX, degreesPerPixelY); canvas.DrawLine(points[0], points[1], paint); lonLineTrackerDegrees += resolutionCell10; } double latLineTrackerDegrees = imageBottom - spaceToFirstLineBottom; //This is degree coords while (latLineTrackerDegrees <= totalArea.NorthLatitude + resolutionCell10) //This means we should always draw at least 2 lines, even if they're off-canvas. { var geoLine = new LineString(new Coordinate[] { new Coordinate(180, latLineTrackerDegrees), new Coordinate(-180, latLineTrackerDegrees) }); var points = PolygonToSKPoints(geoLine, totalArea, degreesPerPixelX, degreesPerPixelY); canvas.DrawLine(points[0], points[1], paint); latLineTrackerDegrees += resolutionCell10; } var ms = new MemoryStream(); var skms = new SkiaSharp.SKManagedWStream(ms); bitmap.Encode(skms, SkiaSharp.SKEncodedImageFormat.Png, 100); var results = ms.ToArray(); skms.Dispose(); ms.Close(); ms.Dispose(); return(results); }
/// <summary> /// Combines 2 images into one, given the shared ImageStats for both supplied images. /// </summary> /// <param name="info">the ImageStats object used to generate both bottom and top tiles.</param> /// <param name="bottomTile">the tile to use as the base of the image. Expected to be opaque.</param> /// <param name="topTile">The tile to layer on top. Expected to be at least partly transparent or translucent.</param> /// <returns></returns> public byte[] LayerTiles(ImageStats info, byte[] bottomTile, byte[] topTile) { SkiaSharp.SKBitmap bitmap = new SkiaSharp.SKBitmap(info.imageSizeX, info.imageSizeY, SkiaSharp.SKColorType.Rgba8888, SkiaSharp.SKAlphaType.Premul); SkiaSharp.SKCanvas canvas = new SkiaSharp.SKCanvas(bitmap); SkiaSharp.SKPaint paint = new SkiaSharp.SKPaint(); canvas.Scale(1, 1, info.imageSizeX / 2, info.imageSizeY / 2); paint.IsAntialias = true; var baseBmp = SkiaSharp.SKBitmap.Decode(bottomTile); var topBmp = SkiaSharp.SKBitmap.Decode(topTile); canvas.DrawBitmap(baseBmp, 0, 0); canvas.DrawBitmap(topBmp, 0, 0); var ms = new MemoryStream(); var skms = new SkiaSharp.SKManagedWStream(ms); bitmap.Encode(skms, SkiaSharp.SKEncodedImageFormat.Png, 100); var output = ms.ToArray(); skms.Dispose(); ms.Close(); ms.Dispose(); return(output); }
public bool Encode(Stream dst, SKEncodedImageFormat format, int quality) { using var wrapped = new SKManagedWStream(dst); return(Encode(wrapped, format, quality)); }