/// <summary> /// Applies quantization to the image. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="source">The image this method extends.</param> /// <param name="quantizer">The quantizer to apply to perform the operation.</param> /// <param name="maxColors">The maximum number of colors to return.</param> /// <returns>The <see cref="Image{TPixel}"/>.</returns> public static IImageProcessingContext <TPixel> Quantize <TPixel>(this IImageProcessingContext <TPixel> source, IQuantizer <TPixel> quantizer, int maxColors) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => { // TODO : move helper logic into the processor QuantizedImage <TPixel> quantized = quantizer.Quantize(img.Frames.RootFrame, maxColors); int palleteCount = quantized.Palette.Length - 1; using (Buffer2D <TPixel> pixels = source.MemoryManager.Allocate2D <TPixel>(quantized.Width, quantized.Height)) { Parallel.For( 0, pixels.Height, img.GetConfiguration().ParallelOptions, y => { Span <TPixel> row = pixels.GetRowSpan(y); int yy = y * pixels.Width; for (int x = 0; x < pixels.Width; x++) { int i = x + yy; TPixel color = quantized.Palette[Math.Min(palleteCount, quantized.Pixels[i])]; row[x] = color; } }); Buffer2D <TPixel> .SwapContents(img.Frames[0].PixelBuffer, pixels); } })); }
public static IImageProcessingContext <TPixel> ApplyScalingWaterMarkWordWrap <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); float targetMinHeight = img.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 < targetMinHeight) { 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, img.Height / 2); img.Mutate(i => i.DrawText(text, scaledFont, color, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, WrapTextWidth = targetWidth })); })); }
/// <summary> /// Resizes an image to the given width and height with the given sampler and /// source rectangle. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <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="Image{TPixel}"/></returns> /// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks> public static IImageProcessingContext <TPixel> Resize <TPixel>(this IImageProcessingContext <TPixel> source, int width, int height, IResampler sampler, Rectangle targetRectangle, bool compand) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => { // TODO : stop cheating here and move this stuff into the processors itself if (width == 0 && height > 0) { width = (int)MathF.Round(img.Width * height / (float)img.Height); targetRectangle.Width = width; } if (height == 0 && width > 0) { height = (int)MathF.Round(img.Height * width / (float)img.Width); targetRectangle.Height = height; } Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); img.Mutate(x => x.ApplyProcessor(new ResizeProcessor <TPixel>(sampler, width, height, targetRectangle) { Compand = compand })); })); }
public static IImageProcessingContext <TPixel> EnsureMaximumSize <TPixel>(this IImageProcessingContext <TPixel> source, int maxWidth, int maxHeight, bool maintainAspectRatio = true) where TPixel : struct, IPixel <TPixel> { return(source.Apply(image => { if ((image.Width > maxWidth) || (image.Height > maxHeight)) { if (maintainAspectRatio) { // Handle if width is larger. if (image.Width > image.Height) { image.Mutate(x => x.Resize(maxWidth, Convert.ToInt32(image.Height * maxWidth / image.Width))); } // Else height is larger. else { image.Mutate(x => x.Resize(Convert.ToInt32(image.Width * maxHeight / image.Height), maxHeight)); } } else { image.Mutate(x => x.Resize(maxWidth, maxHeight)); } } })); }
/// <summary> /// Applies quantization to the image. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="source">The image this method extends.</param> /// <param name="quantizer">The quantizer to apply to perform the operation.</param> /// <param name="maxColors">The maximum number of colors to return.</param> /// <returns>The <see cref="Image{TPixel}"/>.</returns> public static IImageProcessingContext <TPixel> Quantize <TPixel>(this IImageProcessingContext <TPixel> source, IQuantizer <TPixel> quantizer, int maxColors) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => { // TODO : move helper logic into the processor QuantizedImage <TPixel> quantized = quantizer.Quantize(img.Frames.RootFrame, maxColors); int palleteCount = quantized.Palette.Length - 1; using (var pixels = new PixelAccessor <TPixel>(quantized.Width, quantized.Height)) { Parallel.For( 0, pixels.Height, img.GetConfiguration().ParallelOptions, y => { for (int x = 0; x < pixels.Width; x++) { int i = x + (y * pixels.Width); TPixel color = quantized.Palette[Math.Min(palleteCount, quantized.Pixels[i])]; pixels[x, y] = color; } }); img.Frames[0].SwapPixelsBuffers(pixels); } })); }
public static IImageProcessingContext <TPixel> ApplyScalingLogoWaterMark <TPixel>( this IImageProcessingContext <TPixel> processingContext, byte[] watermark) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply( image => { // Dispose of logo once used. using (var logo = Image.Load <TPixel>(watermark)) { bool worh = image.Width > image.Height; double coff = worh ? image.Width * 0.127 / Math.Min(logo.Width, logo.Height) : image.Height * 0.127 / Math.Max(logo.Width, logo.Height); var size = new Size((int)(logo.Width * coff), (int)(logo.Height * coff)); var location = new Point(image.Width - size.Width - 57, image.Height - size.Height - 271); // Resize the logo logo.Mutate(i => i.Resize(size)); image.Mutate(i => i.DrawImage(logo, location, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.SrcOver, 1f)); } })); }
/// <summary> /// 画圆圈(泡泡) /// </summary> /// <typeparam name="TPixel"></typeparam> /// <param name="processingContext"></param> /// <param name="containerWidth"></param> /// <param name="containerHeight"></param> /// <param name="count"></param> /// <param name="miniR"></param> /// <param name="maxR"></param> /// <param name="color"></param> /// <param name="canOverlap"></param> /// <returns></returns> public static IImageProcessingContext <TPixel> DrawingCircles <TPixel>(this IImageProcessingContext <TPixel> processingContext, int containerWidth, int containerHeight, int count, int miniR, int maxR, TPixel color, bool canOverlap = false) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(img => { EllipsePolygon ep = null; Random random = new Random(); PointF tempPoint = new PointF(); List <PointF> points = new List <PointF>(); if (count > 0) { for (int i = 0; i < count; i++) { if (canOverlap) { tempPoint = new PointF(random.Next(0, containerWidth), random.Next(0, containerHeight)); } else { tempPoint = getCirclePoginF(containerWidth, containerHeight, (miniR + maxR), ref points); } ep = new EllipsePolygon(tempPoint, random.Next(miniR, maxR)); img.Mutate(ctx => ctx .Draw(color, (float)(random.Next(94, 145) / 100.0), ep.Clip()) ); } } })); }
public static IImageProcessingContext <TPixel> SetAlphaMask <TPixel>(this IImageProcessingContext <TPixel> source, Image <Alpha8> mask, PixelAlphaCompositionMode mode) where TPixel : struct, IPixel <TPixel> { if (mask == null) { return(source); } return(source.Apply ( img => { if (mask.Width == img.Width && mask.Height == img.Height) { using (var rmask = mask.CloneAs <TPixel>()) { img.Mutate(dc => dc.DrawImage(rmask, PixelColorBlendingMode.Normal, mode, 1)); } } else { using (var rmask = mask.CloneAs <TPixel>()) { rmask.Mutate(dc => dc.Resize(img.Width, img.Height)); img.Mutate(dc => dc.DrawImage(rmask, PixelColorBlendingMode.Normal, mode, 1)); } } } )); }
/// <summary> /// 绘制中文字符(可以绘制字母数字,但样式可能需要改) /// </summary> /// <typeparam name="TPixel"></typeparam> /// <param name="processingContext"></param> /// <param name="containerWidth"></param> /// <param name="containerHeight"></param> /// <param name="text"></param> /// <param name="color"></param> /// <param name="font"></param> /// <returns></returns> public static IImageProcessingContext <TPixel> DrawingCnText <TPixel>(this IImageProcessingContext <TPixel> processingContext, int containerWidth, int containerHeight, string text, Rgba32 color, Font font) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(img => { if (string.IsNullOrEmpty(text) == false) { Random random = new Random(); var textWidth = (img.Width / text.Length); var img2Size = Math.Min(textWidth, img.Height); var fontMiniSize = (int)(img2Size * 0.6); var fontMaxSize = (int)(img2Size * 0.95); for (int i = 0; i < text.Length; i++) { using (Image <Rgba32> img2 = new Image <Rgba32>(img2Size, img2Size)) { Font scaledFont = new Font(font, random.Next(fontMiniSize, fontMaxSize)); var point = new Point(i * textWidth, (containerHeight - img2.Height) / 2); var textGraphicsOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }; img2.Mutate(ctx => ctx .DrawText(textGraphicsOptions, text[i].ToString(), scaledFont, color, new Point(0, 0)) .Rotate(random.Next(-45, 45)) ); img.Mutate(ctx => ctx.DrawImage(img2, point, 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, img.Height / 2); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; img.Mutate(i => i.DrawText(textGraphicOptions, text, scaledFont, color, center)); })); }
public static IImageProcessingContext <Rgba32> CreateLayerFromBoundingBox(this IImageProcessingContext <Rgba32> context, BaseBoundingBox boundingBox, string param) { return(context.Apply(img => { using (var layer = new Image <Rgba32>(img.Width, img.Height)) { boundingBox.SetInput(param); layer.Mutate(i => boundingBox.Apply(i)); img.Mutate(i => i.DrawImage(layer, 1.0f, new Point(0, 0))); } })); }
// 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 })); })); }
/// <summary> /// 画杂线 /// </summary> /// <typeparam name="TPixel"></typeparam> /// <param name="processingContext"></param> /// <param name="containerWidth"></param> /// <param name="containerHeight"></param> /// <param name="color"></param> /// <param name="count"></param> /// <param name="thickness"></param> /// <returns></returns> public static IImageProcessingContext <TPixel> DrawingGrid <TPixel>(this IImageProcessingContext <TPixel> processingContext, int containerWidth, int containerHeight, TPixel color, int count, float thickness) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(img => { var points = new List <PointF> { new PointF(0, 0) }; for (int i = 0; i < count; i++) { getCirclePoginF(containerWidth, containerHeight, 9, ref points); } points.Add(new PointF(containerWidth, containerHeight)); img.Mutate(ctx => ctx .DrawLines(color, thickness, points.ToArray()) ); })); }
public static IImageProcessingContext <TPixel> DrawingEnText <TPixel>(this IImageProcessingContext <TPixel> processingContext, int containerWidth, int containerHeight, string text, string[] colorHexArr, Font[] fonts, int gridCoefficient = 6) where TPixel : struct, IPixel <TPixel> { if (gridCoefficient < 0) { gridCoefficient = 0; } return(processingContext.Apply(img => { if (string.IsNullOrEmpty(text) == false) { Random random = new Random(); var textWidth = (img.Width / text.Length); var img2Size = Math.Min(textWidth, img.Height); var fontMiniSize = (int)(img2Size * 0.9); var fontMaxSize = (int)(img2Size * 1.37); Array fontStyleArr = Enum.GetValues(typeof(FontStyle)); for (int i = 0; i < text.Length; i++) { using (Image <Rgba32> img2 = new Image <Rgba32>(img2Size, img2Size)) { Font scaledFont = new Font(fonts[random.Next(0, fonts.Length)], random.Next(fontMiniSize, fontMaxSize), (FontStyle)fontStyleArr.GetValue(random.Next(fontStyleArr.Length))); var point = new Point(i * textWidth, (containerHeight - img2.Height) / 2); var colorHex = colorHexArr[random.Next(0, colorHexArr.Length)]; var textGraphicsOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }; img2.Mutate(ctx => ctx .DrawText(textGraphicsOptions, text[i].ToString(), scaledFont, Rgba32.FromHex(colorHex), new Point(0, 0)) .DrawingGrid(containerWidth, containerHeight, Rgba32.FromHex(colorHex), gridCoefficient, 1) .Rotate(random.Next(-45, 45)) ); img.Mutate(ctx => ctx.DrawImage(img2, point, 1)); } } } })); }
public static IImageProcessingContext <TPixel> ApplyFaceInfo <TPixel>(this IImageProcessingContext <TPixel> processingContext, IList <FaceDetails> faces, TPixel color, TPixel textColor) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(img => { var gfxOptions = new GraphicsOptions(true) { }; var gfxTextOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; var font = SystemFonts.CreateFont("Arial", 39, FontStyle.Bold); foreach (var face in faces) { PointF left_top = new PointF((float)face.BoundingBox.X, (float)face.BoundingBox.Y); PointF left_bottom = new PointF((float)face.BoundingBox.X, (float)face.BoundingBox.Y + (float)face.BoundingBox.Height); PointF right_top = new PointF((float)face.BoundingBox.X + (float)face.BoundingBox.Width, (float)face.BoundingBox.Y); PointF right_bottom = new PointF((float)face.BoundingBox.X + (float)face.BoundingBox.Width, (float)face.BoundingBox.Y + (float)face.BoundingBox.Height); PointF[] boundingBox = new PointF[] { left_top, right_top, right_bottom, left_bottom }; img.Mutate(i => i.DrawPolygon(color, 5f, boundingBox, gfxOptions)); PointF text_Age_pos = new PointF((float)face.BoundingBox.X + (float)face.BoundingBox.Width / 2, (float)face.BoundingBox.Y - 45f); SizeF size = TextMeasurer.Measure($"{face.Age}", new RendererOptions(font) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Origin = text_Age_pos }); PointF[] text_Background_Age = new PointF[] { new PointF(text_Age_pos.X - size.Width / 2 - 20f, text_Age_pos.Y - 20f), new PointF(text_Age_pos.X + size.Width / 2 + 20f, text_Age_pos.Y - 20f), new PointF(text_Age_pos.X + size.Width / 2 + 20f, text_Age_pos.Y + size.Height - 10f), new PointF(text_Age_pos.X - size.Width / 2 - 20f, text_Age_pos.Y + size.Height - 10f) }; img.Mutate(i => i.FillPolygon(color, text_Background_Age, gfxOptions)); img.Mutate(i => i.DrawText($"{face.Age}", font, textColor, text_Age_pos, gfxTextOptions)); PointF text_Emotion_pos = new PointF((float)face.BoundingBox.X + (float)face.BoundingBox.Width / 2, (float)face.BoundingBox.Y + (float)face.BoundingBox.Height + 45f); size = TextMeasurer.Measure($"{face.Emotion}", new RendererOptions(font)); PointF[] text_Background_Emotion = new PointF[] { new PointF(text_Emotion_pos.X - size.Width / 2 - 20f, text_Emotion_pos.Y - 20f), new PointF(text_Emotion_pos.X + size.Width / 2 + 20f, text_Emotion_pos.Y - 20f), new PointF(text_Emotion_pos.X + size.Width / 2 + 20f, text_Emotion_pos.Y + size.Height - 10f), new PointF(text_Emotion_pos.X - size.Width / 2 - 20f, text_Emotion_pos.Y + size.Height - 10f) }; img.Mutate(i => i.FillPolygon(color, text_Background_Emotion, gfxOptions)); img.Mutate(i => i.DrawText($"{face.Emotion}", font, textColor, text_Emotion_pos, gfxTextOptions)); } })); }
/* * 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, img.Height / 2); * var textGraphicOptions = new TextGraphicsOptions(true) * { * HorizontalAlignment = HorizontalAlignment.Center, * VerticalAlignment = VerticalAlignment.Center * }; * img.Mutate(i => i.DrawText(textGraphicOptions, text, scaledFont, color, center)); * }); * } */ private static void ApplyScalingWaterMarkSimpleTopLeft <TPixel>( this IImageProcessingContext <TPixel> p_processingContext, Font p_font, string p_text, TPixel p_fontColor, TPixel p_backgroundColor, float p_targetSize) where TPixel : struct, IPixel <TPixel> { p_processingContext.Apply(p_img => { var targetSizePercent = 100 / p_targetSize; // measure the text size var size = TextMeasurer.Measure(p_text, new RendererOptions(p_font)); //find out how much we need to scale the text to fill the space (up or down) var scalingFactor = Math.Min(p_img.Width / targetSizePercent / size.Width, p_img.Height / targetSizePercent / size.Height); //create a new font var scaledFont = new Font(p_font, scalingFactor * p_font.Size); size = TextMeasurer.Measure(p_text, new RendererOptions(scaledFont)); var center = new PointF(p_img.Width / 75.0f + size.Width / 2, p_img.Height / 75.0f + size.Height / 2); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; p_img.Mutate(p_i => p_i.FillPolygon(new GraphicsOptions(true, PixelColorBlendingMode.Multiply, 0.5f), p_backgroundColor, new PointF(0, 0), new PointF(0, size.Height * 2), new PointF(size.Width + p_img.Width / 75 * 2, size.Height * 2), new PointF(size.Width + p_img.Width / 75 * 2, 0))); p_img.Mutate(p_i => p_i.DrawText(textGraphicOptions, p_text, scaledFont, p_fontColor, center)); }); }
/// <summary> /// Resizes an image in accordance with the given <see cref="ResizeOptions"/>. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="source">The image to resize.</param> /// <param name="options">The resize options.</param> /// <returns>The <see cref="Image{TPixel}"/></returns> /// <remarks>Passing zero for one of height or width within the resize options will automatically preserve the aspect ratio of the original image</remarks> public static IImageProcessingContext <TPixel> Resize <TPixel>(this IImageProcessingContext <TPixel> source, ResizeOptions options) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => { // Cheat and bound through a run, inside here we should just be mutating, this really needs moving over to a processor // Ensure size is populated across both dimensions. if (options.Size.Width == 0 && options.Size.Height > 0) { options.Size = new Size((int)MathF.Round(img.Width * options.Size.Height / (float)img.Height), options.Size.Height); } if (options.Size.Height == 0 && options.Size.Width > 0) { options.Size = new Size(options.Size.Width, (int)MathF.Round(img.Height * options.Size.Width / (float)img.Width)); } Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(img.Frames.RootFrame, options); img.Mutate(x => Resize(x, options.Size.Width, options.Size.Height, options.Sampler, targetRectangle, options.Compand)); })); }
public static IImageProcessingContext <HalfSingle> FillMandelbrot(this IImageProcessingContext <HalfSingle> source, double ox, double oy, double scale, int iterations) { return(source.Apply(image => image._FillMandelbrot(ox, oy, scale, iterations))); }
public static IImageProcessingContext <TPixel> FillCheckers <TPixel>(this IImageProcessingContext <TPixel> source, int cellWidth, int cellHeight, TPixel oddColor, TPixel evenColor) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => img._FillCheckers(cellWidth, cellHeight, oddColor, evenColor))); }
public static IImageProcessingContext <TPixel> SetSubjectInfo <TPixel>(this IImageProcessingContext <TPixel> source, SubjectInfo sinfo) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => img.SetSubjectInfo(sinfo))); }
public static IImageProcessingContext <TPixel> OuterGlow <TPixel>(this IImageProcessingContext <TPixel> source, float radius) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => _ApplyOuterGlow(img, radius))); }
public static IImageProcessingContext <TPixel> PremultiplyAlpha <TPixel>(this IImageProcessingContext <TPixel> source) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => _ApplyAlphaPremultiply(img.ToPixelSampler()))); }
public static IImageProcessingContext <TPixel> ApplyCommonEffect <TPixel>(this IImageProcessingContext <TPixel> source, CommonEffect <TPixel> effect) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => _ApplyCommonEffect <TPixel>(img, effect))); }
public static IImageProcessingContext <TPixel> FillRGB <TPixel>(this IImageProcessingContext <TPixel> source, TPixel rgb) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => _FillRGB(img.ToPixelSampler(), rgb.ToVector4()))); }
public static IImageProcessingContext <TPixel> EdgePaddingAlpha <TPixel>(this IImageProcessingContext <TPixel> source, float minAlpha) where TPixel : struct, IPixel <TPixel> { return(source.Apply(img => _ApplyEdgePadding(img, minAlpha, int.MaxValue))); }
public static IImageProcessingContext <HalfSingle> FillRandomNoise(this IImageProcessingContext <HalfSingle> source, int blurRadius = 0, int randomSeed = 177) { return(source.Apply(image => image._FillRandomNoise(blurRadius, randomSeed))); }
public static IImageProcessingContext <TPixel> ApplyPolarDistort <TPixel>(this IImageProcessingContext <TPixel> dc, bool inverse) where TPixel : struct, IPixel <TPixel> { return(dc.Apply(image => image._DistortImage(inverse))); }
public static IImageProcessingContext <HalfSingle> FillPerlinNoise(this IImageProcessingContext <HalfSingle> source, float scale = 16, int repeat = 0, int octaves = 8, double persistence = 0.1f, int randomSeed = 177) { return(source.Apply(image => image._FillPerlinNoise(scale, repeat, octaves, persistence, randomSeed))); }
public static IImageProcessingContext <TPixel> ApplyScalingWaterMarkWordWrap <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); float targetMinHeight = img.Height - (padding * 3); // must be with in a margin width of the target height // now we are working i 2 dimensions at once and can't just scale because it will cause the text to // reflow we need to just try multiple times var scaledFont = font; SizeF s = new SizeF(float.MaxValue, float.MaxValue); float scaleFactor = (scaledFont.Size / 2);// everytime we change direction we half this size 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 < targetMinHeight) { 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, img.Height / 2); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center, WrapTextWidth = targetWidth }; img.Mutate(i => i.DrawText(textGraphicOptions, text, scaledFont, color, center)); })); }
public static IImageProcessingContext <TPixel> ApplyScalingedText <TPixel>(this IImageProcessingContext <TPixel> processingContext, Font font, string text, string highlight, TPixel color, TPixel colorHighlight, float padding, int maxFontSize) where TPixel : struct, IPixel <TPixel> { return(processingContext.Apply(image => { float targetWidth = image.Width - (padding * 2); float targetHeight = image.Height - (padding * 2); float targetMinHeight = image.Height - (padding * 3) - 100; // must be with in a margin width of the target height // now we are working in 2 dimensions at once and can't just scale because it will cause the text to // reflow we need to just try multiple times var scaledFont = font; SizeF s = new SizeF(float.MaxValue, float.MaxValue); float scaleFactor = (scaledFont.Size / 2);// everytime we change direction we half this size 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 < targetMinHeight) { if (!isTooSmall) { scaleFactor = scaleFactor / 2; } scaledFont = new Font(scaledFont, scaledFont.Size + scaleFactor); isTooSmall = true; } trapCount--; s = TextMeasurer.Measure(text, new RendererOptions(scaledFont) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, WrappingWidth = targetWidth }); } var location = new PointF(padding, padding); var textGraphicOptions = new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, WrapTextWidth = targetWidth }; if (scaledFont.Size > maxFontSize) { scaledFont = new Font(scaledFont, maxFontSize); } image.Mutate(ctx => { foreach (string word in text.Split(new[] { ' ' }, options: System.StringSplitOptions.None)) { var wordSize = TextMeasurer.Measure(word, new RendererOptions(scaledFont) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top //WrappingWidth = targetWidth }); // Wort zu langen. Umbrechen. if (location.X + wordSize.Width > targetWidth) { //location = new PointF(padding, location.Y + wordSize.Height); location = new PointF(padding, location.Y + scaledFont.Size); } foreach (char c in word + " ") { ctx.DrawText(textGraphicOptions, c.ToString(), scaledFont, color, location); var charSize = TextMeasurer.Measure(c.ToString(), new RendererOptions(scaledFont) { HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }); location = new PointF(location.X + charSize.Width, location.Y); } } //ctx.DrawText(textGraphicOptions, text, scaledFont, color, location); //ctx.DrawText(textGraphicOptions, highlight, scaledFont, colorHighlight, location); }); })); }