Search code examples
c#.netasp.net-core.net-coreimagesharp

'IImageProcessingContext' does not contain a definition for 'ApplyScalingWaterMark' ImageSharp


I am running the latest version and I am getting the error as preceding.

Severity Code Description Project File Line Suppression State Error CS1061 'IImageProcessingContext' does not contain a definition for 'ApplyScalingWaterMark' and no accessible extension method 'ApplyScalingWaterMark' accepting a first argument of type 'IImageProcessingContext' could be found (are you missing a using directive or an assembly reference?) GitHubFuncs C:\Sibeesh\Github\GitHubFuncs\GetLatestPosts.cs 39 Active

When I run the code below.

using(var img = Image.Load("canvas.jpg")) {
    Font font = SystemFonts.CreateFont("Arial", 10);
    using
    var img2 = img.Clone(ctx => ctx.ApplyScalingWaterMark(font, feedItem.Summary.Text, Color.HotPink, 5, true));
    img2.Save("images/wrapped.png");
}

Already added the using statements.

using SixLabors.Fonts;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

What am I missing here? Is this an issue with the latest version?


Solution

  • Finally, I got it working. I just had to add a few extension methods.

    using SixLabors.Fonts;
    using SixLabors.ImageSharp;
    using SixLabors.ImageSharp.Drawing.Processing;
    using SixLabors.ImageSharp.Processing;
    using System;
    
    namespace GitHubFuncs.ExtensionMethods {
        public static class ImageSharpExtensions {
            public static IImageProcessingContext ApplyScalingWaterMark(this IImageProcessingContext processingContext,
                Font font,
                string text,
                Color color,
                float padding,
                bool wordwrap) {
                if (wordwrap) {
                    return processingContext.ApplyScalingWaterMarkWordWrap(font, text, color, padding);
                } else {
                    return processingContext.ApplyScalingWaterMarkSimple(font, text, color, padding);
                }
            }
            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);
    
                // 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);
            }
    
            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); // 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;
                FontRectangle s = new FontRectangle(0, 0, float.MaxValue, float.MaxValue);
    
                float scaleFactor = (scaledFont.Size / 2); // every time 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, imgSize.Height / 2);
                var textGraphicOptions = new TextGraphicsOptions() {
                    TextOptions = {
                        HorizontalAlignment = HorizontalAlignment.Left,
                        VerticalAlignment = VerticalAlignment.Center,
                        WrapTextWidth = targetWidth
                    }
                };
                return processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center);
            }
        }
    }
    

    And in the end, I could use this method as preceding.

    private static string WriteOnImage(SyndicationItem feedItem) {
        using var img = Image.Load("images/canvas.jpg");
        var font = SystemFonts.CreateFont("Arial", 20);
        using var img2 = img.Clone(ctx => ctx.ApplyScalingWaterMark(font, feedItem.Summary.Text, Color.White, 5, true));
        return img2.ToBase64String(PngFormat.Instance);
    }