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); }