/// <summary> /// Draw square boxes around each area to approximate how they would behave in an offline app /// </summary> /// <param name="info">the image information for drawing</param> /// <param name="items">the elements to draw.</param> /// <returns>byte array of the generated .png tile image</returns> public byte[] DrawOfflineEstimatedAreas(ImageStats info, List <DbTables.Place> items) { SKBitmap bitmap = new SKBitmap(info.imageSizeX, info.imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul); SKCanvas canvas = new SKCanvas(bitmap); var bgColor = SKColors.Transparent; canvas.Clear(bgColor); canvas.Scale(1, -1, info.imageSizeX / 2, info.imageSizeY / 2); SKPaint fillpaint = new SKPaint(); fillpaint.IsAntialias = true; fillpaint.Style = SKPaintStyle.Fill; var strokePaint = new SKPaint(); strokePaint.Color = SKColors.Black; strokePaint.TextSize = 32; strokePaint.StrokeWidth = 3; strokePaint.Style = SKPaintStyle.Stroke; strokePaint.TextAlign = SKTextAlign.Center; //TagParser.ApplyTags(items); var placeInfo = PraxisCore.Standalone.Standalone.GetPlaceInfo(items.Where(i => i.IsGameElement ).ToList()); //this is for rectangles. foreach (var pi in placeInfo) { var rect = PlaceInfoToRect(pi, info); fillpaint.Color = SKColor.Parse(TagParser.PickStaticColorForArea(pi.Name)); canvas.DrawRect(rect, fillpaint); canvas.DrawRect(rect, strokePaint); } canvas.Scale(1, -1, info.imageSizeX / 2, info.imageSizeY / 2); //inverts the inverted image again! foreach (var pi in placeInfo) { var rect = PlaceInfoToRect(pi, info); canvas.DrawText(pi.Name, rect.MidX, info.imageSizeY - rect.MidY, strokePaint); } var ms = new MemoryStream(); var skms = new SKManagedWStream(ms); bitmap.Encode(skms, SKEncodedImageFormat.Png, 100); var results = ms.ToArray(); skms.Dispose(); ms.Close(); ms.Dispose(); return(results); }
/// <summary> /// Draw square boxes around each area to approximate how they would behave in an offline app /// </summary> /// <param name="info">the image information for drawing</param> /// <param name="items">the elements to draw.</param> /// <returns>byte array of the generated .png tile image</returns> public byte[] DrawOfflineEstimatedAreas(ImageStats info, List <DbTables.Place> items) { //TODO retest this. var image = new Image <Rgba32>(info.imageSizeX, info.imageSizeY); var bgColor = Rgba32.ParseHex("00000000"); image.Mutate(x => x.Fill(bgColor)); var fillColor = Rgba32.ParseHex("000000"); var strokeColor = Rgba32.ParseHex("000000"); var placeInfo = Standalone.Standalone.GetPlaceInfo(items.Where(i => i.IsGameElement ).ToList()); //this is for rectangles. foreach (var pi in placeInfo) { var rect = PlaceInfoToRect(pi, info); fillColor = Rgba32.ParseHex(TagParser.PickStaticColorForArea(pi.Name)); image.Mutate(x => x.Fill(fillColor, rect)); image.Mutate(x => x.Draw(strokeColor, 3, rect)); } image.Mutate(x => x.Flip(FlipMode.Vertical));; //inverts the inverted image again! foreach (var pi in placeInfo) { //NOTE: would be better to load fonts once and share that for the app's lifetime. var fonts = new SixLabors.Fonts.FontCollection(); var family = fonts.Add("fontHere.ttf"); var font = family.CreateFont(12, FontStyle.Regular); var rect = PlaceInfoToRect(pi, info); image.Mutate(x => x.DrawText(pi.Name, font, strokeColor, new PointF((float)(pi.lonCenter * info.pixelsPerDegreeX), (float)(pi.latCenter * info.pixelsPerDegreeY)))); } image.Mutate(x => x.Flip(FlipMode.Vertical)); //Plus codes are south-to-north, so invert the image to make it correct. var ms = new MemoryStream(); image.SaveAsPng(ms); return(ms.ToArray()); }