private static IImageProcessingContext ApplyScalingWaterMarkSimple(IImageProcessingContext processingContext, Font font, string text, Color color, float padding) { Size imgSize = processingContext.GetCurrentSize(); float targetWidth = imgSize.Width - (padding * 2); float targetHeight = imgSize.Height - (padding * 2); // measure the text size FontRectangle 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(imgSize.Width / size.Width, imgSize.Height / size.Height); //create a new font Font scaledFont = new Font(font, scalingFactor * font.Size); var center = new PointF(imgSize.Width / 2, imgSize.Height / 2); var textGraphicOptions = new TextGraphicsOptions() { TextOptions = { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center } }; return(processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center)); }
// Colors: Red,Blue,Purple,#006666 private static IImageProcessingContext DrawWatermark(this IImageProcessingContext context, WatermarkSettings settings) { var imgSize = context.GetCurrentSize(); // measure the text size var size = TextMeasurer.Measure(settings.Text, new RendererOptions(settings.TextFont)); //find out how much we need to scale the text to fill the space (up or down) var scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height) / 3; //create a new settings.TextFont var scaledFont = new Font(settings.TextFont, scalingFactor * settings.TextFont.Size); var center = settings.Position switch { WatermarkPosition.Top => new PointF(imgSize.Width / 2, (imgSize.Height / 9)), WatermarkPosition.TopLeft => new PointF(imgSize.Width / 2, (imgSize.Height / 9)), WatermarkPosition.TopRight => new PointF(imgSize.Width / 2, (imgSize.Height / 9)), _ => new PointF(imgSize.Width / 2, imgSize.Height - (imgSize.Height / 9)), }; var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }; // Apply Banner context.DrawBanner(settings) .DrawText(textGraphicOptions, settings.Text, scaledFont, settings.TextColor, center); return(context); }
private static IImageProcessingContext DrawBanner(this IImageProcessingContext context, WatermarkSettings settings) { var imgSize = context.GetCurrentSize(); var options = new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.SrcOver, 1); var points = new[] { new PointF(0, imgSize.Height), new PointF(imgSize.Width, imgSize.Height) }; var stop = 0; IBrush brush = new LinearGradientBrush( points[0], points[1], GradientRepetitionMode.Repeat, settings.Colors.Select(x => new ColorStop(stop++, x)).ToArray()); var thickness = imgSize.Height / 4.5; var center = imgSize.Height - thickness; if ((settings.Position == WatermarkPosition.Top) || (settings.Position == WatermarkPosition.TopLeft) || (settings.Position == WatermarkPosition.TopRight)) { points = new[] { new PointF(0, 0), new PointF(imgSize.Width, 0) }; } var fullThickness = (float)(thickness * 2); var pen = new Pen(brush, fullThickness); var polygon = new Polygon(new LinearLineSegment(points)); return(context.Draw(options, pen, polygon)); }
public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options) { // simply draw a full-height lines either side of the vent var startPixel = options.Converters.SecondsToPixels(this.EventStartSeconds); graphics.NoAA().DrawLines( options.Border, new PointF(startPixel, 0), new PointF(startPixel, graphics.GetCurrentSize().Height)); var endPixel = options.Converters.SecondsToPixels(this.EventEndSeconds); graphics.NoAA().DrawLines( options.Border, new PointF(endPixel, 0), new PointF(endPixel, graphics.GetCurrentSize().Height)); }
/// <summary> /// Resizes an image to the given width and height with the given sampler and source rectangle. /// </summary> /// <param name="source">The image to resize.</param> /// <param name="width">The target image width.</param> /// <param name="height">The target image height.</param> /// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param> /// <param name="targetRectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the target image object to draw to. /// </param> /// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> /// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image or the nearest possible ratio.</remarks> public static IImageProcessingContext Resize( this IImageProcessingContext source, int width, int height, IResampler sampler, Rectangle targetRectangle, bool compand) => source.ApplyProcessor(new ResizeProcessor(sampler, width, height, source.GetCurrentSize(), targetRectangle, compand));
public static IImageProcessingContext DrawTextCentered( this IImageProcessingContext context, string text, Font font, Color color, int height) => // ReSharper disable once PossibleLossOfFraction DrawTextCentered(context, text, font, color, new PointF(context.GetCurrentSize().Width / 2, height));
public static void Round(this IImageProcessingContext <Rgba32> img, float radius) { var size = img.GetCurrentSize(); var gOptions = new GraphicsOptions(true) { AlphaCompositionMode = PixelAlphaCompositionMode.DestOut }; img.Fill(gOptions, Rgba32.Black, BuildCorners(size.Width, size.Height, radius)); }
private static void DrawProfileName(IImageProcessingContext context, string name, bool isRtl) { const int nameMaxWidth = 330; var pointX = 79; if (isRtl) { pointX = context.GetCurrentSize().Width - pointX - 330; } context.DrawText(name, 32, "#fff", new Size(nameMaxWidth, 40), new Point(pointX, 419)); }
private static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { var(width, height) = ctx.GetCurrentSize(); var corners = BuildCorners(width, height, cornerRadius); var graphicOptions = new GraphicsOptions(enableAntialiasing: true) { AlphaCompositionMode = PixelAlphaCompositionMode.DestOut }; return(ctx.Fill(graphicOptions, Rgba32.Red, corners)); }
private static void DrawProfileImage(IImageProcessingContext context, Image <Rgba32> profileImage, bool isRtl) { const int offsetOfImage = 135; var pointX = offsetOfImage; if (isRtl) { pointX = context.GetCurrentSize().Width - offsetOfImage - profileImage.Width; } profileImage.Mutate(x => x.ApplyRoundedCorners(SquareProfileImageDimension / 2f)); context.DrawImage(profileImage, new Point(pointX, 135), GraphicsOptions.Default); }
public static IImageProcessingContext ApplyWatermark(this IImageProcessingContext processingContext, string watermarkFile, double?opacity) { if (File.Exists(watermarkFile)) { using var watermarkImage = Image.Load(watermarkFile); var size = processingContext.GetCurrentSize(); watermarkImage.Mutate(x => x.Resize(size)); processingContext.DrawImage(watermarkImage, PixelColorBlendingMode.Overlay, (float)(opacity ?? 0.95)); } return(processingContext); }
private static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { var size = ctx.GetCurrentSize(); var corners = BuildCorners(size.Width, size.Height, cornerRadius); var graphicOptions = new GraphicsOptions(true) { AlphaCompositionMode = PixelAlphaCompositionMode.DestOut // enforces that any part of this shape that has color is punched out of the background }; return(ctx.Fill(graphicOptions, Rgba32.LimeGreen, corners)); }
public static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { Size size = ctx.GetCurrentSize(); IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius); ctx.SetGraphicsOptions(new GraphicsOptions() { Antialias = true, AlphaCompositionMode = PixelAlphaCompositionMode.DestOut }); return(ctx.Fill(Color.Red, corners)); }
public static IImageProcessingContext ApplyWatermark(this IImageProcessingContext processingContext, WatermarkConfiguration config) { if (config is null) { return(processingContext); } else if (!string.IsNullOrEmpty(config.SourceFile)) { return(processingContext.ApplyWatermark(config.SourceFile, config.Opacity)); } var settings = WatermarkSettings.FromConfig(config); var size = processingContext.GetCurrentSize(); // Create a new image for the watermark layer. using var watermark = new Image <Rgba32>(size.Width, size.Height); var xOffeset = 0; var yOffeset = 0; watermark.Mutate(ctx => { // Draw the watermark. ctx.DrawWatermark(settings); var angle = 0.0f; if ((settings.Position == WatermarkPosition.BottomLeft) || (settings.Position == WatermarkPosition.TopRight)) { angle = 45.0f; // Calculate the x/y offsets for later when we draw the watermark on top of the source image. xOffeset = -(int)((Math.Sin(angle) * (size.Width / 2)) / 2); yOffeset = -(int)((Math.Sin(angle) * (size.Height / 2)) / 2); } else if ((settings.Position == WatermarkPosition.BottomRight) || (settings.Position == WatermarkPosition.TopLeft)) { angle = -45.0f; // Calculate the x/y offsets for later when we draw the watermark on top of the source image. xOffeset = (int)((Math.Sin(angle) * (size.Width / 2)) / 2); yOffeset = (int)((Math.Sin(angle) * (size.Height / 2)) / 2); } if (angle != 0) { ctx.Rotate(angle); } }); // Draw the watermark layer on top of the source image. processingContext.DrawImage(watermark, new Point(xOffeset, yOffeset), 1); return(processingContext); }
// This method can be seen as an inline implementation of an `IImageProcessor`: // (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`) private static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { Size size = ctx.GetCurrentSize(); IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius); var graphicOptions = new GraphicsOptions(true) { AlphaCompositionMode = PixelAlphaCompositionMode.DestOut // enforces that any part of this shape that has color is punched out of the background }; // mutating in here as we already have a cloned original // use any color (not Transparent), so the corners will be clipped return(ctx.Fill(graphicOptions, Rgba32.LimeGreen, corners)); }
public static void ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { var(width, height) = ctx.GetCurrentSize(); var corners = BuildCorners(width, height, cornerRadius); var graphicOptions = new GraphicsOptions(true) { AlphaCompositionMode = PixelAlphaCompositionMode.DestOut // Enforces that any part of this shape that has color is punched out of the background }; // Mutating in here as we already have a cloned original // use any color (not Transparent), so the corners will be clipped ctx.Fill(graphicOptions, Rgba32.LimeGreen, corners); }
public static IImageProcessingContext ApplyRoundedCorners( this IImageProcessingContext ctx) { (int width, int height) = ctx.GetCurrentSize(); IPathCollection corners = BuildCorners(width, height); var graphicOptions = new GraphicsOptions(true) { // enforces that any part of this shape that has color is punched out of the background AlphaCompositionMode = PixelAlphaCompositionMode.DestOut }; // use any color (not Transparent), so the corners will be clipped return(ctx.Fill(graphicOptions, Rgba32.LimeGreen, corners)); }
public static IImageProcessingContext <TPixel> Resize <TPixel>(this IImageProcessingContext <TPixel> source, Size target) where TPixel : struct, IPixel <TPixel> { if (target.Width == 0 && target.Height == 0) { return(source); } var origin = source.GetCurrentSize(); if (target.Width == 0) { var rate = (float)origin.Height / target.Height; if (rate <= 1) { return(source); } return(source.Resize <TPixel>((int)(origin.Width / rate), target.Height, KnownResamplers.Bicubic, false)); } if (target.Height == 0) { var rate = (float)origin.Width / target.Width; if (rate <= 1) { return(source); } return(source.Resize <TPixel>(target.Width, (int)(origin.Height / rate), KnownResamplers.Bicubic, false)); } var size = new Size(); var r = Math.Max(((float)origin.Width / target.Width), ((float)origin.Height) / target.Height); if (r <= 1) { return(source); } size.Width = (int)Math.Round(origin.Width / r); size.Height = (int)Math.Round(origin.Height / r); if (size.Width == 0) { size.Width = 1; } if (size.Height == 0) { size.Height = 1; } return(source.Resize <TPixel>(size, KnownResamplers.Bicubic, false)); }
public static void ResizeCanvas(this IImageProcessingContext context, double?pad, string padColorNameOrHexString) { if (pad is null || pad.Value < 1) { return; } var scale = (double)pad; var color = ColorUtils.TryParse(padColorNameOrHexString, out var result) ? result : Color.Transparent; var size = context.GetCurrentSize(); var height = (int)(size.Height * scale); var width = (int)(size.Width * scale); context.Pad(width, height, color); }
// https://github.com/SixLabors/Samples/blob/master/ImageSharp/AvatarWithRoundedCorner/Program.cs public static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { Size size = ctx.GetCurrentSize(); IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius); ctx.SetGraphicsOptions(new GraphicsOptions() { Antialias = true, AlphaCompositionMode = PixelAlphaCompositionMode.DestOut // enforces that any part of this shape that has color is punched out of the background }); foreach (var c in corners) { ctx = ctx.Fill(SixLabors.ImageSharp.Color.Red, c); } return(ctx); }
// This method can be seen as an inline implementation of an `IImageProcessor`: // (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`) private static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius) { Size size = ctx.GetCurrentSize(); IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius); ctx.SetGraphicsOptions(new GraphicsOptions() { Antialias = true, AlphaCompositionMode = PixelAlphaCompositionMode.DestOut // enforces that any part of this shape that has color is punched out of the background }); // mutating in here as we already have a cloned original // use any color (not Transparent), so the corners will be clipped foreach (var c in corners) { ctx = ctx.Fill(Color.Red, c); } return(ctx); }
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)); }
/// <summary> /// Resizes an image to the given width and height with the given sampler and /// source rectangle. /// </summary> /// <param name="source">The image to resize.</param> /// <param name="width">The target image width.</param> /// <param name="height">The target image height.</param> /// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param> /// <param name="sourceRectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw. /// </param> /// <param name="targetRectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the target image object to draw to. /// </param> /// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> /// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image or the nearest possible ratio.</remarks> public static IImageProcessingContext Resize( this IImageProcessingContext source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand) { var options = new ResizeOptions { Size = new Size(width, height), Mode = ResizeMode.Manual, Sampler = sampler, TargetRectangle = targetRectangle, Compand = compand }; return(source.ApplyProcessor(new ResizeProcessor(options, source.GetCurrentSize()), sourceRectangle)); }
/// <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)); }
private static IImageProcessingContext ApplyScalingWaterMarkSimple(this IImageProcessingContext processingContext, Font font, string text, Color color, float padding) { Size imgsize = processingContext.GetCurrentSize(); float targetWidth = imgsize.Width - (padding * 2); float targetHeight = imgsize.Height - (padding * 2); SizeF size = TextMeasurer.Measure(text, new RendererOptions(font)); float scalingFactor = Math.Min(imgsize.Width / size.Width, imgsize.Height / size.Height); Font scaledFont = new Font(font, scalingFactor * font.Size); var center = new PointF(imgsize.Width / 2, imgsize.Height / 2); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; return(processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center)); }
public static IImageProcessingContext ApplyScalingWaterMark(this IImageProcessingContext processingContext, string text, Color color) { var(width, height) = processingContext.GetCurrentSize(); var font = SystemFonts.CreateFont("Arial", 10); var size = TextMeasurer.Measure(text, new RendererOptions(font)); var scalingFactor = Math.Min(width / size.Width, height / size.Height); var scaledFont = new Font(font, scalingFactor * font.Size); var center = new PointF(width / 2, height / 2); var textGraphicOptions = new TextGraphicsOptions { TextOptions = { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }, GraphicsOptions = { BlendPercentage = (float)0.2, Antialias = true } }; return(processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center)); }
/// <summary> /// Skews an image by the given angles in degrees using the specified sampling algorithm. /// </summary> /// <param name="source">The image to skew.</param> /// <param name="degreesX">The angle in degrees to perform the skew along the x-axis.</param> /// <param name="degreesY">The angle in degrees to perform the skew along the y-axis.</param> /// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext Skew( this IImageProcessingContext source, float degreesX, float degreesY, IResampler sampler) => source.ApplyProcessor(new SkewProcessor(degreesX, degreesY, sampler, source.GetCurrentSize()));
private static IImageProcessingContext ApplyScalingWaterMarkWordWrap( this IImageProcessingContext processingContext, Font font, string text, Color color, float padding) { Size imgSize = processingContext.GetCurrentSize(); float targetWidth = imgSize.Width - (padding * 2); float targetHeight = imgSize.Height - (padding * 2); float targetMinHeight = imgSize.Height - (padding * 3); var scaledFont = font; SizeF s = new SizeF(float.MaxValue, float.MaxValue); float scaleFactor = (scaledFont.Size) / 2; int trapCount = (int)scaledFont.Size * 2; if (trapCount > 10) { trapCount = 10; } bool isTooSmall = false; while ((s.Height > targetHeight || s.Height < targetMinHeight) && trapCount > 0) { if (s.Height > targetHeight) { if (isTooSmall) { scaleFactor = scaleFactor / 2; } scaledFont = new Font(scaledFont, scaledFont.Size - scaleFactor); isTooSmall = false; } if (s.Height < targetHeight) { if (!isTooSmall) { scaleFactor = scaleFactor / 2; } scaledFont = new Font(scaledFont, scaledFont.Size + scaleFactor); isTooSmall = true; } trapCount--; s = TextMeasurer.Measure(text, new RendererOptions(scaledFont) { WrappingWidth = targetWidth }); } var center = new PointF(padding, imgSize.Height / 2); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center, WrapTextWidth = targetWidth }; return(processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center)); }
/// <summary> /// Transforms an image by the given matrix using the specified sampling algorithm. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="source">The image to transform.</param> /// <param name="matrix">The transformation matrix.</param> /// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param> /// <returns>The <see cref="Image{TPixel}"/></returns> public static IImageProcessingContext <TPixel> Transform <TPixel>(this IImageProcessingContext <TPixel> source, Matrix3x2 matrix, IResampler sampler) where TPixel : struct, IPixel <TPixel> => source.ApplyProcessor(new AffineTransformProcessor <TPixel>(matrix, sampler, source.GetCurrentSize()));
/// <summary> /// Crops an image to the given rectangle. /// </summary> /// <param name="source">The image to crop.</param> /// <param name="cropRectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to retain. /// </param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext Crop(this IImageProcessingContext source, Rectangle cropRectangle) => source.ApplyProcessor(new CropProcessor(cropRectangle, source.GetCurrentSize()));