public static string GenerateFront(string name, Roles role, string filePath) { string hexcode = "#0B1133"; string border = "Cards/hero_frontoverlay.png"; if (role == Roles.Villain) { border = "Cards/villain_frontoverlay.png"; hexcode = "#670000"; } else if (role == Roles.Rogue) { border = "Cards/rogue_frontoverlay.png"; hexcode = "#350022"; } var fontCollection = new FontCollection(); var parentFont = fontCollection.Install("Cards/front.tff").CreateFont(50, FontStyle.Bold); var childFont = parentFont; using (Image <Rgba32> backgroundImage = Image.Load(filePath)) { using (Image <Rgba32> borderImage = Image.Load(border)) { int fontSize = 50; float textOffset = 0; while (true) { var size = TextMeasurer.Measure(name, new RendererOptions(childFont)); if (size.Width > 350) { fontSize -= 5; childFont = new Font(parentFont, fontSize); continue; } textOffset = 250 - size.Width / 2; break; } backgroundImage.Mutate(x => x.Resize(new ResizeOptions() { Mode = ResizeMode.Crop, Size = new Size(500, 700), Position = AnchorPositionMode.Top }).DrawImage(borderImage, 1).DrawText(name, childFont, Brushes.Solid(Rgba32.FromHex("#FFFFFF")), Pens.Solid(Rgba32.FromHex(hexcode), 8), new PointF(textOffset, 630)).DrawText(name, childFont, Brushes.Solid(Rgba32.FromHex("#FFFFFF")), new PointF(textOffset, 630))); backgroundImage.Save($"Cards/Done/front-{name}.png"); return($"Cards/Done/front-{name}.png"); } } }
private Size MeasureText(TextRun text) { if (string.IsNullOrWhiteSpace(text.Text)) { return(new Size(0, 0)); } // TODO: Support text.Formatting.FormattingType var family = SystemFonts.Find("Arial"); var font = new Font(family, (float)text.Formatting.Size, FontStyle.Regular); var size = TextMeasurer.Measure(text.Text, new RendererOptions(font, 72)); return(new Size(size.Width, size.Height)); }
private RectangleF MeasureString(string text, Font font) { RendererOptions options = new RendererOptions(font); FontRectangle rectangle = TextMeasurer.Measure(text == "" ? " " : text, options); if (text == "") { return(new RectangleF(0, rectangle.Y, 0, rectangle.Height)); } else { return(new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height)); } }
/// <summary> /// NOTE: either filePath or bytes should be set at the same time /// </summary> /// <returns>Base64 image data</returns> public string GetImage(string text, bool active, string value = null, string imageOnFilePath = null, byte[] imageOnBytes = null, string imageOffFilePath = null, byte[] imageOffBytes = null) { var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); var valueFont = SystemFonts.CreateFont("Arial", 15, FontStyle.Regular); bool hasValue = value != null && value.Length > 0; // Note: logic to choose with image to show // 1. If user did not select custom images, the active image (with light) is used // only when Feedback value is true AND Display value is empty. // 2. If user select custom images (esp Active one), the custom Active image is used based on Feedback value // ignoring Display value. var img = active ? GetBackgroundImage(imageOnBytes, imageOnFilePath, !hasValue ? defaultActiveBackground : defaultBackground) : GetBackgroundImage(imageOffBytes, imageOffFilePath, defaultBackground); using var img2 = img.Clone(ctx => { ctx.Resize(WIDTH, WIDTH); // Force image to rescale to our button size, otherwise text gets super small if it is bigger. var imgSize = ctx.GetCurrentSize(); // Calculate scaling for header var smallerDim = imgSize.Width < imgSize.Height ? imgSize.Width : imgSize.Height; var scale = 1f; if (smallerDim != WIDTH) { scale = (float)smallerDim / WIDTH; font = new Font(font, font.Size * scale); valueFont = new Font(valueFont, valueFont.Size * scale); } FontRectangle size; if (!string.IsNullOrWhiteSpace(text)) { size = TextMeasurer.Measure(text, new RendererOptions(font)); ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 4)); } if (hasValue) { size = TextMeasurer.Measure(value, new RendererOptions(valueFont)); ctx.DrawText(value, valueFont, active ? Color.Yellow : Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, 46 * scale)); } }); return(ToBase64PNG(img2)); }
// From https://github.com/SixLabors/Samples/blob/master/ImageSharp/DrawWaterMarkOnImage/Program.cs public static IImageProcessingContext <TPixel> ApplyScalingWaterMarkSimple <TPixel>(this IImageProcessingContext <TPixel> processingContext, Font font, TPixel color, float padding, int scalingFactor, string text) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(img => { SizeF size = TextMeasurer.Measure(text, new RendererOptions(font)); Font scaledFont = new Font(font, Math.Min(img.Width, img.Height) / scalingFactor * font.Size); var pos = new PointF(img.Width - padding, img.Height - padding); img.Mutate(i => i.DrawText(text, scaledFont, color, pos, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Bottom })); })); }
/// <returns>Base64 image data</returns> public string GetNumberImage(int number) { var font = SystemFonts.CreateFont("Arial", 20, FontStyle.Bold); var text = number.ToString(); using var img = defaultBackground.Clone(ctx => { var imgSize = ctx.GetCurrentSize(); var size = TextMeasurer.Measure(text, new RendererOptions(font)); ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 2 - size.Height / 2)); }); return(ToBase64PNG(img)); }
public static string AddWrap(this string text, Font font, float maxWidth, int maxWraps = 5) { float textWidth = TextMeasurer.Measure(text, new RendererOptions(font)).Width; if (textWidth < maxWidth) { return(text); } var sb = new StringBuilder(); float currentWidth = 0; var currentWraps = 0; var words = text.Split(' '); var emptyCharSize = TextMeasurer.Measure(" ", new RendererOptions(font)); foreach (var word in words) { var wordSize = TextMeasurer.Measure(word, new RendererOptions(font)); if (wordSize.Width + currentWidth < maxWidth) { currentWidth += wordSize.Width; currentWidth += emptyCharSize.Width; //We need to add the size of an empty space too } else { if (currentWraps + 1 > maxWraps) { sb.Append("..."); break; } sb.AppendLine(); currentWraps++; currentWidth = 0; } sb.Append(word); sb.Append(' '); } return(sb.ToString()); }
public string GetNavComImage(string type, bool dependant, string value1 = null, string value2 = null, bool showMainOnly = false, string imageOnFilePath = null, byte[] imageOnBytes = null) { var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); var valueFont = SystemFonts.CreateFont("Arial", showMainOnly ? 26 : 15, FontStyle.Regular); Image img = defaultBackground; if (imageOnBytes != null && imageOnBytes.Length > 0) { img = Image.Load(imageOnBytes, new PngDecoder()); } else if (!string.IsNullOrEmpty(imageOnFilePath) && File.Exists(imageOnFilePath)) { img = Image.Load(imageOnFilePath); } img.Mutate(x => x.Resize(WIDTH, WIDTH)); //force image to rescale to our button size, otherwise text gets super small if it is bigger. using var img2 = img.Clone(ctx => { var imgSize = ctx.GetCurrentSize(); if (!string.IsNullOrWhiteSpace(type)) { var size = TextMeasurer.Measure(type, new RendererOptions(font)); Color displayColor = dependant ? Color.White : Color.LightGray; ctx.DrawText(type, font, displayColor, new PointF(imgSize.Width / 2 - size.Width / 2, showMainOnly ? imgSize.Height / 4 : imgSize.Height / 6)); } if (!string.IsNullOrWhiteSpace(value1)) { var size1 = TextMeasurer.Measure(value1, new RendererOptions(valueFont)); Color displayColor = dependant ? Color.Yellow : Color.LightGray; ctx.DrawText(value1, valueFont, displayColor, new PointF(imgSize.Width / 2 - size1.Width / 2, showMainOnly ? (imgSize.Height / 2) : (imgSize.Height / 6 + imgSize.Height / 4))); } if (!string.IsNullOrWhiteSpace(value2) && !showMainOnly) { var size2 = TextMeasurer.Measure(value2, new RendererOptions(valueFont)); Color displayColor = dependant ? Color.White : Color.LightGray; ctx.DrawText(value2, valueFont, displayColor, new PointF(imgSize.Width / 2 - size2.Width / 2, imgSize.Height / 6 + imgSize.Height / 4 + size2.Height)); } }); using var memoryStream = new MemoryStream(); img2.Save(memoryStream, new PngEncoder()); var base64 = Convert.ToBase64String(memoryStream.ToArray()); return("data:image/png;base64, " + base64); }
public static void RenderTextProcessorWithAlignment( FontFamily fontFamily, string text, float pointSize = 12, IEnumerable <FontFamily> fallbackFonts = null) { foreach (VerticalAlignment va in (VerticalAlignment[])Enum.GetValues(typeof(VerticalAlignment))) { foreach (HorizontalAlignment ha in (HorizontalAlignment[])Enum.GetValues(typeof(HorizontalAlignment))) { Font font = new(fontFamily, pointSize); TextOptions textOptions = new(font) { Dpi = 96, VerticalAlignment = va, HorizontalAlignment = ha, }; if (fallbackFonts != null) { textOptions.FallbackFontFamilies = fallbackFonts.ToArray(); } FontRectangle textSize = TextMeasurer.Measure(text, textOptions); using var img = new Image <Rgba32>(((int)textSize.Width * 2) + 20, ((int)textSize.Height * 2) + 20); Size size = img.Size(); textOptions.Origin = new PointF(size.Width / 2F, size.Height / 2F); img.Mutate(x => x.Fill(Color.Black).ApplyProcessor( new DrawTextProcessor( x.GetDrawingOptions(), textOptions, text, new SolidBrush(Color.Yellow), null))); img[size.Width / 2, size.Height / 2] = Color.White; string h = ha.ToString().Replace(nameof(HorizontalAlignment), string.Empty).ToLower(); string v = va.ToString().Replace(nameof(VerticalAlignment), string.Empty).ToLower(); string fullPath = CreatePath(font.Name, text + "-" + h + "-" + v + ".png"); Directory.CreateDirectory(IOPath.GetDirectoryName(fullPath)); img.Save(fullPath); } } }
/// <summary> /// 添加水印 /// </summary> /// <param name="watermarkText">水印文字</param> /// <param name="color">水印颜色</param> /// <param name="watermarkPosition">水印位置</param> /// <param name="textPadding">边距</param> /// <param name="font">字体</param> /// <returns></returns> public MemoryStream AddWatermark(string watermarkText, Font font, Color color, WatermarkPosition watermarkPosition = WatermarkPosition.BottomRight, int textPadding = 10) { using var img = Image.Load(_stream); if (SkipWatermarkForSmallImages && (img.Height < Math.Sqrt(SmallImagePixelsThreshold) || img.Width < Math.Sqrt(SmallImagePixelsThreshold))) { return(_stream as MemoryStream ?? _stream.SaveAsMemoryStream()); } if (img.Width / font.Size > 50) { font = font.Family.CreateFont(img.Width * 1f / 50); } var measure = TextMeasurer.Measure(watermarkText, new TextOptions(font)); float x, y; textPadding += (img.Width - 1000) / 100; switch (watermarkPosition) { case WatermarkPosition.TopRight: x = img.Width - measure.Width - textPadding; y = textPadding; break; case WatermarkPosition.BottomLeft: x = textPadding; y = img.Height - measure.Height - textPadding; break; case WatermarkPosition.BottomRight: x = img.Width - measure.Width - textPadding; y = img.Height - measure.Height - textPadding; break; default: x = textPadding; y = textPadding; break; } img.Mutate(c => c.DrawText(watermarkText, font, color, new PointF(x, y))); var ms = new MemoryStream(); img.SaveAsWebp(ms); ms.Position = 0; return(ms); }
public static string AddWrap(this string text, Font font, float maxWidth, int maxWraps = 5) { float textWidth = TextMeasurer.Measure(text, new RendererOptions(font)).Width; if (maxWraps == 0) { return($"{text.Substring(0, (int)maxWidth - 3)}..."); } if (textWidth < maxWidth) { return(text); } string fittingTextLine = String.Empty; List <string> words = text.Split(' ').ToList(); var addedWords = 0; for (var i = 0; i < words.Count - 1; i++) { var word = words[i]; var fittingTextLineWidth = TextMeasurer.Measure(fittingTextLine, new RendererOptions(font)).Width; var wordWidth = TextMeasurer.Measure(word, new RendererOptions(font)).Width; if (fittingTextLineWidth + wordWidth <= maxWidth) { fittingTextLine += $" {word}"; addedWords++; } else { break; } } if (addedWords < words.Count) { fittingTextLine += "\n" + words.Skip(addedWords).Take(words.Count - addedWords).Aggregate((i, j) => i + " " + j).AddWrap(font, maxWidth, maxWraps - 1); } // Remove first space fittingTextLine = fittingTextLine.Substring(1, fittingTextLine.Length - 2); return(fittingTextLine); }
public string GetGaugeImage(string text, float value, float min, float max) { var font = SystemFonts.CreateFont("Arial", 25, FontStyle.Regular); var titleFont = SystemFonts.CreateFont("Arial", 15, FontStyle.Regular); var pen = new Pen(Color.DarkRed, 5); var range = max - min; if (range <= 0) { range = 1; } using var img = gaugeImage.Clone(ctx => { double angleOffset = Math.PI * -1.25; double angle = Math.PI * ((value - min) / range) + angleOffset; var startPoint = new PointF(HALF_WIDTH, HALF_WIDTH); var middlePoint = new PointF( (float)((HALF_WIDTH - 16) * Math.Cos(angle)), (float)((HALF_WIDTH - 16) * Math.Sin(angle)) ); var endPoint = new PointF( (float)(HALF_WIDTH * Math.Cos(angle)), (float)(HALF_WIDTH * Math.Sin(angle)) ); PointF[] needle = { startPoint + middlePoint, startPoint + endPoint }; ctx.DrawLines(pen, needle); var size = TextMeasurer.Measure(text, new RendererOptions(titleFont)); ctx.DrawText(text, titleFont, Color.White, new PointF(HALF_WIDTH - size.Width / 2, 57)); var valueText = value.ToString(); size = TextMeasurer.Measure(valueText, new RendererOptions(font)); ctx.DrawText(valueText, font, Color.White, new PointF(25, 30)); }); using var memoryStream = new MemoryStream(); img.Save(memoryStream, new PngEncoder()); var base64 = Convert.ToBase64String(memoryStream.ToArray()); return("data:image/png;base64, " + base64); }
/// <inheritdoc/> public override OxySize MeasureText(string text, string fontFamily = null, double fontSize = 10, double fontWeight = 500) { var font = GetFontOrThrow(fontFamily, fontSize, FontStyle.Regular); text = text ?? string.Empty; /* * We use DPI 72 for measurements on purpose. See: * https://github.com/SixLabors/ImageSharp/issues/421 * When this issue is resolved in ImageSharp, we should * pass the correct dpi here. */ var dpiOverride = 72; var result = TextMeasurer.Measure(text, new RendererOptions(font, dpiOverride)); return(new OxySize(result.Width, result.Height)); }
/// <summary> /// Captions an image with top text and bottom text (Impact font). /// </summary> /// <param name="imageFilename">Path to the input image.</param> /// <param name="topText">Top text to render.</param> /// <param name="bottomText">Bottom text to render.</param> /// <returns>The image with the given text drawn on it.</returns> public static Image MemeCaptionImage(string imageFilename, string topText, string bottomText) { Image image = Image.Load(imageFilename); //calculate font size based on largest image dimension int fontSize = image.Width > image.Height ? image.Width / 12 : image.Height / 12; Font font = SystemFonts.CreateFont("Impact", fontSize); //compute text render size and font outline size FontRectangle botTextSize = TextMeasurer.Measure(bottomText, new RendererOptions(font)); float outlineSize = fontSize / 15.0f; //determine top & bottom text location float padding = 10f; float textMaxWidth = image.Width - (padding * 2); //determine how much to vertically offset bottom text (need to account for word wrap) int wordWrapOffsetFactor = (int)Math.Ceiling(botTextSize.Width / textMaxWidth); PointF topLeftLocation = new PointF(padding, padding); PointF bottomLeftLocation = new PointF(padding, image.Height - botTextSize.Height * wordWrapOffsetFactor - padding * 2); //white brush for text fill and black pen for text outline SolidBrush brush = new SolidBrush(Color.White); Pen pen = new Pen(Color.Black, outlineSize); TextGraphicsOptions options = new TextGraphicsOptions() { TextOptions = new TextOptions() { WrapTextWidth = textMaxWidth, HorizontalAlignment = HorizontalAlignment.Center } }; //render text if (!string.IsNullOrEmpty(topText)) { image.Mutate(x => x.DrawText(options, topText, font, brush, pen, topLeftLocation)); } if (!string.IsNullOrEmpty(bottomText)) { image.Mutate(x => x.DrawText(options, bottomText, font, brush, pen, bottomLeftLocation)); } return(image); }
private Font GetFontSize(FontFamily fontFamily, float size, string text, float maxWidth) { var font = new Font(fontFamily, size); var measured = TextMeasurer.Measure(text, new RendererOptions(font)); while (measured.Width > maxWidth) { if (--size < 1) { break; } font = new Font(fontFamily, size); measured = TextMeasurer.Measure(text, new RendererOptions(font)); } return(font); }
/// <summary> /// /// </summary> /// <returns>Base64 image data</returns> public string GetImage(string text, bool active, string value = null, string customActiveBackground = null, string customBackground = null) { var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); var valueFont = SystemFonts.CreateFont("Arial", 15, FontStyle.Regular); bool hasValue = value != null && value.Length > 0; // Note: logic to choose with image to show // 1. If user did not select custom images, the active image (with light) is used // only when Feedback value is true AND Display value is empty. // 2. If user select custom images (esp Active one), the custom Active image is used based on Feedback value // ignoring Display value. Image img; if (active) { img = !string.IsNullOrEmpty(customActiveBackground) && File.Exists(customActiveBackground) ? Image.Load(customActiveBackground) : (!hasValue ? defaultActiveBackground : defaultBackground); } else { img = !string.IsNullOrEmpty(customBackground) && File.Exists(customBackground) ? Image.Load(customBackground) : defaultBackground; } using var img2 = img.Clone(ctx => { var imgSize = ctx.GetCurrentSize(); FontRectangle size; if (!string.IsNullOrWhiteSpace(text)) { size = TextMeasurer.Measure(text, new RendererOptions(font)); ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 4)); } if (hasValue) { size = TextMeasurer.Measure(value, new RendererOptions(valueFont)); ctx.DrawText(value, valueFont, active ? Color.Yellow : Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, 46)); } }); using var memoryStream = new MemoryStream(); img2.Save(memoryStream, new PngEncoder()); var base64 = Convert.ToBase64String(memoryStream.ToArray()); return("data:image/png;base64, " + base64); }
public void DrawText(string text, HorizontalAlignment halign, VerticalAlignment valign, FontSize fontSize = FontSize.Small, int margin = 4) { var font = fonts[fontSize]; #if IMAGESHARP_V2 var options = new TextOptions(font); #else var options = new RendererOptions(font); #endif var size = TextMeasurer.Measure(text, options); var aligned = Align((int)size.Width, (int)size.Height, halign, valign, margin); if (DebugMode) { _ = Context.Draw(Pens.Solid(Color.Red, 1f), aligned); } _ = Context.DrawText(text, font, Color.White, new PointF(aligned.X, aligned.Y)); }
private Font ResizeFont(Font font, string text, int maxWidth, FontStyle fontStyle = FontStyle.Regular) { int initialFonzSize = (int)font.Size; while (true) { if (TextMeasurer.Measure(text, new RendererOptions(font)).Width > maxWidth) { initialFonzSize--; font = new Font(font.Family, initialFonzSize, fontStyle); } else { break; } } return(font); }
public PlaceholdImage GenerateImage(DefaultImageRequest request) { using var image = request.ToImage(); if (string.IsNullOrWhiteSpace(request.Text)) { return(SaveImage(image, request)); } float textMaxWidth = request.Width - _padding * 2; // width of image indent left & right by padding Color fontColor = request.TextColor.HexStringToColor(); var family = PlaceholdFontCollection.Instance.Families.FirstOrDefault(x => string.Equals(x.Name, request.Font, StringComparison.CurrentCultureIgnoreCase)); if (family == null) { family = PlaceholdFontCollection.Instance.Families.FirstOrDefault(); } DrawingOptions drawingOptions = new() { TextOptions = new() { WrapTextWidth = textMaxWidth, } }; var font = new Font(family, request.FontSize); var size = TextMeasurer.Measure(request.Text, new RendererOptions(font, 72)); int xPos = (int)((request.Width - size.Width) / 2); if (xPos < 0) { xPos = (int)_padding; } int yPos = (int)((request.Height - size.Height) / 2); image.Mutate(i => i.DrawText(drawingOptions, request.Text, font, fontColor, new PointF(xPos, yPos))); return(SaveImage(image, request)); } }
public async Task ShareAppointmentImageAsync(CalendarEvent c) { var assembly = Assembly.GetExecutingAssembly(); var resourceName = "NSchedule.Fonts.font.ttf"; FontFamily font; FontCollection fonts = new FontCollection(); using (Stream stream = assembly.GetManifestResourceStream(resourceName)) { font = fonts.Install(stream); } var Data = DependencyService.Get <DataHelper>(); var att = c.Appointment.Attendees; var rooms = Data.Schedulables.Where(x => x.GetType() == typeof(Room) && att.Contains(x.Id)).Cast <Room>().Select(x => x.Code); var teachers = Data.Schedulables.Where(x => x.GetType() == typeof(Teacher) && att.Contains(x.Id)).Cast <Teacher>().Select(x => x.Code); var groups = Data.Schedulables.Where(x => x.GetType() == typeof(Group) && att.Contains(x.Id)).Cast <Group>().Select(x => x.Code); string yourText = $"{c.Name}\n{c.ScheduleableCode} ({c.Times})\n\n\nRooms:\n{JoinPerTwo(rooms)}\n\nTeachers:\n{JoinPerTwo(teachers)}\n\nGroups:\n{JoinPerTwo(groups)}\n\n{Constants.SHARED_WITH}"; var f = font.CreateFont(25f); var measures = TextMeasurer.Measure(yourText, new RendererOptions(f)); var img = new Image <Rgba32>((int)measures.Width + 50, (int)measures.Height + 50); img.Mutate(x => x.Fill(Color.White)); IPath rect = new RectangularPolygon(15, 15, measures.Width + 20, measures.Height + 20); img.Mutate(x => x.Draw(Color.Gray, 5f, rect)); img.Mutate(x => x.DrawText(yourText, f, Color.Black, new PointF(25f, 25f))); var basePath = System.IO.Path.GetTempPath(); var path = System.IO.Path.Combine(basePath, "share.png"); await img.SaveAsPngAsync(path).ConfigureAwait(false); await Share.RequestAsync(new ShareFileRequest(c.Name, new ShareFile(path))).ConfigureAwait(false); // cleanup after share.. //File.Delete(path); }
private void GeneratedImageWithCaption(WallpaperFileImage original) { var fileContent = _wallpaperManager.GetFile(_wallpaper, original); if (!fileContent.HasValue) { return; } var caption = CreateCaptions(); if (string.IsNullOrEmpty(caption)) { return; } using (var image = Image.Load(fileContent.Value.Data)) using (var destStream = new MemoryStream()) { var font = _robotoFont.CreateFont(14); var size = TextMeasurer.Measure(caption, new RendererOptions(font)); var bounds = image.Bounds(); var start = (bounds.Width / 2) - (size.Width / 2); var point = new PointF(start, 14); var boxLocation = new RectangleF(point, size); boxLocation.Inflate(4, 4); image.Mutate(x => x.Fill(Rgba32.White, boxLocation)); image.Mutate(x => x.DrawText(caption, font, Rgba32.Black, point)); image.SaveAsPng(destStream); var file = new WallpaperFileWithData() { Data = destStream.ToArray(), FileDto = new WallpaperFileCaption { OriginalFileId = original.FileId, Position = WallpaperFileCaption.WallpaperFileThumbnailPosition.Top } }; _wallpaperManager.AddFile(_wallpaper, file); } }
private static void DrawDifferencesToBitmap(bool absoluteText, int cellsize, Image <Rgba32> img, byte[,] differences, byte maxDifference) { for (int y = 0; y < differences.GetLength(1); y++) { for (int x = 0; x < differences.GetLength(0); x++) { byte cellValue = differences[x, y]; string cellText = null; if (absoluteText) { cellText = cellValue.ToString(); } else { cellText = string.Format("{0}%", (int)cellValue); } float percentageDifference = (float)differences[x, y] / maxDifference; int colorIndex = (int)(255 * percentageDifference); var rect = new RectangleF(x * cellsize, y * cellsize, cellsize, cellsize); img.Mutate(ctx => ctx.Fill(brushes[colorIndex], rect).Draw(Graphics.BluePen, rect)); SizeF size = TextMeasurer.Measure(cellText, new RendererOptions(defaultFont)); PointF point = new PointF((int)(x * cellsize + cellsize / 2 - size.Width / 2 + 1), (int)(y * cellsize + cellsize / 2 - size.Height / 2 + 1)); //Sometimes the string is too long to fit and gives an exception. //Font reduced from 8 to 6 to lessen chance of it happening but for safety we'll ignore. try { img.Mutate(ctx => ctx.DrawText(cellText, defaultFont, Rgba32.Black, point)); } catch (ArgumentOutOfRangeException) { } point = new PointF((int)(x * cellsize + cellsize / 2 - size.Width / 2), (int)(y * cellsize + cellsize / 2 - size.Height / 2)); try { img.Mutate(ctx => ctx.DrawText(cellText, defaultFont, Rgba32.White, point)); } catch (ArgumentOutOfRangeException) { } } } }
private void RenderFontToTexture(Font font, ref ISet <char> requestedSymbols, int textureSize, int padding) { var options = new RendererOptions(font); int x = 0, y = 0, maxHeight = 0; do { var glyphStr = $"{requestedSymbols.First()}"; var glyph = glyphStr[0]; var sizeF = TextMeasurer.Measure(glyphStr, options); var size = new Size((int)Math.Ceiling(sizeF.Width), (int)Math.Ceiling(sizeF.Height)); maxHeight = Math.Max(maxHeight, size.Height); var dstRect = new Rectangle(x, y, size.Width, size.Height); if (dstRect.Right >= textureSize) { // jump onto the next line x = 0; y += maxHeight + padding; maxHeight = 0; dstRect.X = x; dstRect.Y = y; } if (dstRect.Bottom >= textureSize) { // we can't fit letters anymore break; } var shapes = TextBuilder.GenerateGlyphs(glyphStr, new SPointF(x, y), options); Texture.Mutate(m => m.Fill(Rgba32.White, shapes)); _glyphMap.Add(glyph, dstRect); requestedSymbols.Remove(glyph); if (Start == default(char)) { Start = glyph; } End = glyph; x += size.Width + padding; } while (requestedSymbols.Any()); }
protected override Image <Rgba32> Run() { if (!_init) { FontFamily fo; SystemFonts.TryFind("Times New Roman", out fo); var font = new Font(fo, 30, FontStyle.Regular); FontRectangle size = TextMeasurer.Measure( _text, new RendererOptions(font)); Image <Rgba32> loadImage = new Image <Rgba32>(Convert.ToInt32(size.Width) + (2 * LEDPIProcessorBase.LEDWidth), Math.Max(Convert.ToInt32(size.Height), LEDPIProcessorBase.LEDHeight)); SetBackgroundColor(loadImage); loadImage.Mutate(c => c.DrawText( _text, font, Color.LightYellow, new PointF(LEDPIProcessorBase.LEDWidth, (loadImage.Height - size.Height) / 2))); _wholeTextImage = loadImage.Clone(); _init = true; } else { Thread.Sleep(_speed); } if (_offset + LEDPIProcessorBase.LEDWidth > _wholeTextImage.Width) { _offset = 0; } var cropedImage = _wholeTextImage.Clone(); cropedImage.Mutate(c => c.Crop(new Rectangle(_offset++, 0, LEDPIProcessorBase.LEDWidth, LEDPIProcessorBase.LEDHeight))); return(cropedImage); }
/// <returns>Base64 image data</returns> public string GetNumberImage(int number) { var font = SystemFonts.CreateFont("Arial", 20, FontStyle.Bold); var text = number.ToString(); Image img = defaultBackground; using var img2 = img.Clone(ctx => { var imgSize = ctx.GetCurrentSize(); var size = TextMeasurer.Measure(text, new RendererOptions(font)); ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 2 - size.Height / 2)); }); using var memoryStream = new MemoryStream(); img2.Save(memoryStream, new PngEncoder()); var base64 = Convert.ToBase64String(memoryStream.ToArray()); return("data:image/png;base64, " + base64); }
public static int GetRows(Font f, int fontSize, int maxSize) { int maxRows = 0; float totalHeight = 0; while (true) { var size = TextMeasurer.Measure("p", new RendererOptions(new Font(f, fontSize))); totalHeight += size.Height + (fontSize / 5); if (totalHeight > maxSize) { return(maxRows); } else { maxRows += 1; } } }
public static IImageProcessingContext <TPixel> ApplyScalingWaterMarkSimple <TPixel>(this IImageProcessingContext <TPixel> processingContext, Font font, string text, TPixel color, float padding) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(img => { float targetWidth = img.Width - (padding * 2); float targetHeight = img.Height - (padding * 2); // measure the text size SizeF size = TextMeasurer.Measure(text, new RendererOptions(font)); //find out how much we need to scale the text to fill the space (up or down) float scalingFactor = Math.Min(img.Width / size.Width, img.Height / size.Height); //create a new font Font scaledFont = new Font(font, scalingFactor * font.Size); var center = new PointF(img.Width / 2, 20);//img.Height / 2); var c1 = new PointF(center.X - 1, center.Y - 1); var c2 = new PointF(center.X + 1, center.Y - 1); var c3 = new PointF(center.X - 1, center.Y + 1); var c4 = new PointF(center.X + 1, center.Y + 1); img.Mutate(i => { var tempColor = color; tempColor.PackFromRgba32(Rgba32.FromHex("ddddddaa")); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; i.DrawText(textGraphicOptions, text, scaledFont, tempColor, c1); i.DrawText(textGraphicOptions, text, scaledFont, tempColor, c2); i.DrawText(textGraphicOptions, text, scaledFont, tempColor, c3); i.DrawText(textGraphicOptions, text, scaledFont, tempColor, c4); i.DrawText(textGraphicOptions, text, scaledFont, tempColor, center); }); })); }
private static IImageProcessingContext AddCaption(this IImageProcessingContext processingContext, string text, Color color, Color backgroundColor) { Size imgSize = processingContext.GetCurrentSize(); float defaultFontSize = 12; float defaultResolution = 645; float defaultPadding = 10; float fontSize = imgSize.Width * defaultFontSize / defaultResolution; float padding = imgSize.Width * defaultPadding / defaultResolution; float captionWidth = imgSize.Width - (2 * padding); FontCollection collection = new FontCollection(); FontFamily family = collection.Install("Roboto/Roboto-Regular.ttf"); Font font = family.CreateFont(fontSize, FontStyle.Regular); // measure the text size FontRectangle fontRectangle = TextMeasurer.Measure(text, new RendererOptions(font) { WrappingWidth = captionWidth }); var location = new PointF(padding, imgSize.Height + padding); var textGraphicOptions = new TextGraphicsOptions() { TextOptions = { WrapTextWidth = captionWidth } }; var resizeOptions = new ResizeOptions() { // increse image height to include caption height Size = new Size(imgSize.Width, imgSize.Height + (int)fontRectangle.Height + (int)(2 * padding)), Mode = ResizeMode.BoxPad, Position = AnchorPositionMode.Top }; return(processingContext .Resize(resizeOptions) .BackgroundColor(backgroundColor) .DrawText(textGraphicOptions, text, font, color, location)); }
protected virtual int OnExecute(CommandLineApplication app) { using Display display = PiTop4Board.Instance.Display; Font font = SystemFonts.Collection.Find("Roboto").CreateFont(20); display.Draw((context, _) => { context.Clear(Color.Black); FontRectangle rect = TextMeasurer.Measure(Text, new RendererOptions(font)); float x = display.Width / 2 - rect.Width / 2; float y = display.Height / 2 - rect.Height / 2; context.DrawText(Text, font, Color.White, new PointF(x, y)); }); Thread.Sleep(5000); return(0); }
/// <summary> /// Given a SixLabours ImageSharp image context, applies a watermark text overlay /// to the bottom right corner in the given font and colour. /// </summary> /// <param name="processingContext"></param> /// <param name="font"></param> /// <param name="text"></param> /// <param name="color"></param> /// <returns></returns> private static IImageProcessingContext ApplyWaterMark(IImageProcessingContext processingContext, Font font, string text, Color color) { Size imgSize = processingContext.GetCurrentSize(); // measure the text size FontRectangle size = TextMeasurer.Measure(text, new RendererOptions(font)); int ratio = 4; // Landscape, we make the text 25% of the width if (imgSize.Width >= imgSize.Height) { // Landscape - make it 1/6 of the width ratio = 6; } float quarter = imgSize.Width / ratio; // We want the text width to be 25% of the width of the image float scalingFactor = quarter / size.Width; // create a new font Font scaledFont = new Font(font, scalingFactor * font.Size); // 5% padding from the edge float fivePercent = quarter / 20; // 5% from the bottom right. var position = new PointF(imgSize.Width - fivePercent, imgSize.Height - fivePercent); var textGraphicOptions = new TextGraphicsOptions { TextOptions = { HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Bottom, } }; return(processingContext.DrawText(textGraphicOptions, text, scaledFont, color, position)); }