/// <summary> /// Initializes a new instance of the <see cref="GraphicsOptions"/> struct. /// </summary> /// <param name="enableAntialiasing">If set to <c>true</c> [enable antialiasing].</param> public GraphicsOptions(bool enableAntialiasing) { this.blenderMode = PixelBlenderMode.Normal; this.blendPercentage = 1; this.antialiasSubpixelDepth = 16; this.antialias = enableAntialiasing; }
/// <summary> /// Find an instance of the pixel blender. /// </summary> /// <param name="mode">The blending mode to apply</param> /// <returns>A <see cref="PixelBlender{TPixel}"/>.</returns> internal virtual PixelBlender <TPixel> GetPixelBlender(PixelBlenderMode mode) { switch (mode) { case PixelBlenderMode.Multiply: return(DefaultMultiplyPixelBlender <TPixel> .Instance); case PixelBlenderMode.Add: return(DefaultAddPixelBlender <TPixel> .Instance); case PixelBlenderMode.Substract: return(DefaultSubstractPixelBlender <TPixel> .Instance); case PixelBlenderMode.Screen: return(DefaultScreenPixelBlender <TPixel> .Instance); case PixelBlenderMode.Darken: return(DefaultDarkenPixelBlender <TPixel> .Instance); case PixelBlenderMode.Lighten: return(DefaultLightenPixelBlender <TPixel> .Instance); case PixelBlenderMode.Overlay: return(DefaultOverlayPixelBlender <TPixel> .Instance); case PixelBlenderMode.HardLight: return(DefaultHardLightPixelBlender <TPixel> .Instance); case PixelBlenderMode.Normal: default: return(DefaultNormalPixelBlender <TPixel> .Instance); } }
public void _1DarkBlueRect_2BlendHotPinkRect_3BlendTransparentEllipse <TPixel>( TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> img = provider.GetImage()) { int scaleX = img.Width / 100; int scaleY = img.Height / 100; img.Mutate( x => x.Fill( NamedColors <TPixel> .DarkBlue, new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY))); img.Mutate( x => x.Fill( new GraphicsOptions(true) { BlenderMode = mode }, NamedColors <TPixel> .HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY))); img.Mutate( x => x.Fill( new GraphicsOptions(true) { BlenderMode = mode }, NamedColors <TPixel> .Transparent, new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY)) ); VerifyImage(provider, mode, img); } }
private GraphicsOptions createGraphicsOptions(PixelBlenderMode blendmode, float percent) { return(new GraphicsOptions(isAAEnabled) { BlenderMode = blendmode, BlendPercentage = percent }); }
public void BlendFillColorOverBackround <TPixel>( TestImageProvider <TPixel> provider, bool triggerFillRegion, string newColorName, float alpha, PixelBlenderMode blenderMode, float blendPercentage) where TPixel : struct, IPixel <TPixel> { var vec = TestUtils.GetPixelOfNamedColor <RgbaVector>(newColorName).ToVector4(); vec.W = alpha; TPixel fillColor = default; fillColor.PackFromVector4(vec); using (Image <TPixel> image = provider.GetImage()) { TPixel bgColor = image[0, 0]; var options = new GraphicsOptions(false) { BlenderMode = blenderMode, BlendPercentage = blendPercentage }; if (triggerFillRegion) { var region = new ShapeRegion(new RectangularPolygon(0, 0, 16, 16)); image.Mutate(c => c.Fill(options, new SolidBrush <TPixel>(fillColor), region)); } else { image.Mutate(c => c.Fill(options, new SolidBrush <TPixel>(fillColor))); } var testOutputDetails = new { triggerFillRegion = triggerFillRegion, newColorName = newColorName, alpha = alpha, blenderMode = blenderMode, blendPercentage = blendPercentage }; image.DebugSave( provider, testOutputDetails, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); PixelBlender <TPixel> blender = PixelOperations <TPixel> .Instance.GetPixelBlender(blenderMode); TPixel expectedPixel = blender.Blend(bgColor, fillColor, blendPercentage); image.ComparePixelBufferTo(expectedPixel); } }
public void DrawBlendedValues <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (var img = provider.GetImage()) { img.Fill(NamedColors <TPixel> .DarkBlue, new Rectangle(0, 40, 100, 20)); img.Fill(NamedColors <TPixel> .HotPink, new Rectangle(40, 0, 20, 100), new ImageSharp.GraphicsOptions(true) { BlenderMode = mode }); img.DebugSave(provider, new { mode }); } }
/// <summary> /// Initializes a new instance of the <see cref="TextGraphicsOptions" /> struct. /// </summary> /// <param name="enableAntialiasing">If set to <c>true</c> [enable antialiasing].</param> public TextGraphicsOptions(bool enableAntialiasing) { this.applyKerning = true; this.tabWidth = 4; this.useImageResolution = false; this.wrapTextWidth = 0; this.textAlignment = SixLabors.Fonts.TextAlignment.Left; this.antialiasSubpixelDepth = 16; this.blenderMode = PixelBlenderMode.Normal; this.blendPercentage = 1; this.antialias = enableAntialiasing; }
/// <summary> /// Initializes a new instance of the <see cref="TextGraphicsOptions" /> struct. /// </summary> /// <param name="enableAntialiasing">If set to <c>true</c> [enable antialiasing].</param> public TextGraphicsOptions(bool enableAntialiasing) { this.applyKerning = true; this.tabWidth = 4; this.wrapTextWidth = 0; this.horizontalAlignment = HorizontalAlignment.Left; this.verticalAlignment = VerticalAlignment.Top; this.antialiasSubpixelDepth = 16; this.blenderMode = PixelBlenderMode.Normal; this.blendPercentage = 1; this.antialias = enableAntialiasing; }
/// <summary> /// Find an instance of the pixel blender. /// </summary> /// <param name="mode">The blending mode to apply</param> /// <returns>A <see cref="PixelBlender{TPixel}"/>.</returns> internal virtual PixelBlender <TPixel> GetPixelBlender(PixelBlenderMode mode) { switch (mode) { case PixelBlenderMode.Multiply: return(DefaultPixelBlenders <TPixel> .Multiply.Instance); case PixelBlenderMode.Add: return(DefaultPixelBlenders <TPixel> .Add.Instance); case PixelBlenderMode.Subtract: return(DefaultPixelBlenders <TPixel> .Subtract.Instance); case PixelBlenderMode.Screen: return(DefaultPixelBlenders <TPixel> .Screen.Instance); case PixelBlenderMode.Darken: return(DefaultPixelBlenders <TPixel> .Darken.Instance); case PixelBlenderMode.Lighten: return(DefaultPixelBlenders <TPixel> .Lighten.Instance); case PixelBlenderMode.Overlay: return(DefaultPixelBlenders <TPixel> .Overlay.Instance); case PixelBlenderMode.HardLight: return(DefaultPixelBlenders <TPixel> .HardLight.Instance); case PixelBlenderMode.Src: return(DefaultPixelBlenders <TPixel> .Src.Instance); case PixelBlenderMode.Atop: return(DefaultPixelBlenders <TPixel> .Atop.Instance); case PixelBlenderMode.Over: return(DefaultPixelBlenders <TPixel> .Over.Instance); case PixelBlenderMode.In: return(DefaultPixelBlenders <TPixel> .In.Instance); case PixelBlenderMode.Out: return(DefaultPixelBlenders <TPixel> .Out.Instance); case PixelBlenderMode.Dest: return(DefaultPixelBlenders <TPixel> .Dest.Instance); case PixelBlenderMode.DestAtop: return(DefaultPixelBlenders <TPixel> .DestAtop.Instance); case PixelBlenderMode.DestOver: return(DefaultPixelBlenders <TPixel> .DestOver.Instance); case PixelBlenderMode.DestIn: return(DefaultPixelBlenders <TPixel> .DestIn.Instance); case PixelBlenderMode.DestOut: return(DefaultPixelBlenders <TPixel> .DestOut.Instance); case PixelBlenderMode.Clear: return(DefaultPixelBlenders <TPixel> .Clear.Instance); case PixelBlenderMode.Xor: return(DefaultPixelBlenders <TPixel> .Xor.Instance); case PixelBlenderMode.Normal: default: return(DefaultPixelBlenders <TPixel> .Normal.Instance); } }
public void DrawBlendedValues <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (var img = provider.GetImage()) { var scaleX = (img.Width / 100); var scaleY = (img.Height / 100); img.Fill(NamedColors <TPixel> .DarkBlue, new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY)); img.Fill(NamedColors <TPixel> .HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true) { BlenderMode = mode }); img.DebugSave(provider, new { mode }); } }
public void PorterDuffOutputIsCorrect(TestImageProvider <Rgba32> provider, PixelBlenderMode mode) { var srcFile = TestFile.Create(TestImages.Png.PDSrc); using (Image <Rgba32> src = srcFile.CreateImage()) using (Image <Rgba32> dest = provider.GetImage()) { using (Image <Rgba32> res = dest.Clone(x => x.DrawImage(new GraphicsOptions { BlenderMode = mode }, src))) { res.DebugSave(provider, mode.ToString()); res.CompareToReferenceOutput(provider, mode.ToString()); } } }
public IMessage Blend(IMessage message) { if (message.Attachments?.Count >= 2) { int blendAmount = 50; PixelBlenderMode mode = PixelBlenderMode.Normal; List <string> args = message.Text.GetCommandArguments(); if (args.Count > 0) { int.TryParse(args[0], out blendAmount); if (args.Count > 1) { PixelBlenderMode.TryParse(args[1], out mode); } } MemoryStream ms = new MemoryStream(); using (var imageSource = ImageSharp.Image.Load(message.Attachments[0].Contents, out var mimetype)) { imageSource.Save(ms, mimetype); ms.Seek(0, SeekOrigin.Begin); } foreach (IAttachment attachment in message.Attachments.Skip(1)) { using (var imageSource = ImageSharp.Image.Load(ms)) { using (var imageTarget = ImageSharp.Image.Load(attachment.Contents, out var mimetype)) { imageTarget.Mutate(x => x.Resize(imageSource.Width, imageTarget.Width)); ms.Dispose(); ms = new MemoryStream(); // Reinit the stream. This is also insane. imageSource.Mutate(x => x.DrawImage(imageTarget, mode, blendAmount / 100.0f)); imageSource.Save(ms, mimetype); } } attachment.Contents?.Dispose(); ms.Seek(0, SeekOrigin.Begin); } return(Message.Create(null, new StreamAttachment(ms, message.Attachments[0].Name))); } return(null); }
public void _1DarkBlueRect_2BlendHotPinkRect_3BlendSemiTransparentRedEllipse <TPixel>( TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> img = provider.GetImage()) { int scaleX = (img.Width / 100); int scaleY = (img.Height / 100); img.Mutate( x => x.Fill( NamedColors <TPixel> .DarkBlue, new Rectangle(0 * scaleX, 40, 100 * scaleX, 20 * scaleY))); img.Mutate( x => x.Fill( new GraphicsOptions(true) { BlenderMode = mode }, NamedColors <TPixel> .HotPink, new Rectangle(20 * scaleX, 0, 30 * scaleX, 100 * scaleY))); var c = NamedColors <TPixel> .Red.ToVector4(); c.W *= 0.5f; var pixel = default(TPixel); pixel.PackFromVector4(c); img.Mutate( x => x.Fill( new GraphicsOptions(true) { BlenderMode = mode }, pixel, new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY)) ); VerifyImage(provider, mode, img);; } }
/// <summary> /// Draws the given image together with the current one by blending their pixels. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="image">The image to blend with the currently processing image.</param> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="blender">The type of bending to apply.</param> /// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param> /// <param name="location">The location to draw the blended image.</param> /// <returns>The <see cref="Image{TPixel}"/>.</returns> public static IImageProcessingContext <TPixel> DrawImage <TPixel>(this IImageProcessingContext <TPixel> source, Image <TPixel> image, PixelBlenderMode blender, float opacity, Point location) where TPixel : struct, IPixel <TPixel> => source.ApplyProcessor(new DrawImageProcessor <TPixel>(image, location, opacity, blender));
/// <summary> /// Initializes a new instance of the <see cref="DrawImageProcessor{TPixel}"/> class. /// </summary> /// <param name="image">The image to blend with the currently processing image.</param> /// <param name="location">The location to draw the blended image.</param> /// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param> /// <param name="blenderMode">The blending mode to use when drawing the image.</param> public DrawImageProcessor(Image <TPixel> image, Point location, float opacity, PixelBlenderMode blenderMode) { Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity)); this.Image = image; this.Opacity = opacity; this.Blender = PixelOperations <TPixel> .Instance.GetPixelBlender(blenderMode); this.Location = location; }
/// <summary> /// Initializes a new instance of the <see cref="DrawImageProcessor{TPixel}"/> class. /// </summary> /// <param name="image">The image to blend with the currently processing image.</param> /// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param> /// <param name="blenderMode">The blending mode to use when drawing the image.</param> public DrawImageProcessor(Image <TPixel> image, float opacity, PixelBlenderMode blenderMode) : this(image, Point.Empty, opacity, blenderMode) { }
public void ImageShouldApplyDrawImage <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) using (Image <TPixel> blend = Image.Load <TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes)) { image.DrawImage(blend, mode, .75f, new Size(image.Width / 2, image.Height / 2), new Point(image.Width / 4, image.Height / 4)) .DebugSave(provider, new { mode }); } }
/// <summary> /// Draws the given image together with the current one by blending their pixels. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="image">The image to blend with the currently processing image.</param> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="blender">The type of bending to apply.</param> /// <param name="percent">The opacity of the image image to blend. Must be between 0 and 1.</param> /// <param name="size">The size to draw the blended image.</param> /// <param name="location">The location to draw the blended image.</param> /// <returns>The <see cref="Image{TPixel}"/>.</returns> public static IImageProcessingContext <TPixel> DrawImage <TPixel>(this IImageProcessingContext <TPixel> source, Image <TPixel> image, PixelBlenderMode blender, float percent, Size size, Point location) where TPixel : struct, IPixel <TPixel> { GraphicsOptions options = GraphicsOptions.Default; options.BlenderMode = blender; options.BlendPercentage = percent; return(source.DrawImage(image, size, location, options)); }
public void ImageShouldDrawTransformedImage <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) using (Image <TPixel> blend = Image.Load <TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes)) { Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(45F); Matrix3x2 scale = Matrix3x2Extensions.CreateScale(new SizeF(.25F, .25F)); blend.Mutate(x => x.Transform(rotate * scale)); var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2); image.Mutate(x => x.DrawImage(blend, mode, .75F, new Size(blend.Width, blend.Height), position)); image.DebugSave(provider, new[] { "Transformed" }); } }
public void ReturnsCorrectBlender <TPixel>(TestPixel <TPixel> pixel, Type type, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { PixelBlender <TPixel> blender = PixelOperations <TPixel> .Instance.GetPixelBlender(mode); Assert.IsType(type, blender); }
public void ImageShouldDrawTransformedImage <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) using (var blend = Image.Load <TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes)) { Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(45F); Matrix3x2 scale = Matrix3x2Extensions.CreateScale(new SizeF(.25F, .25F)); Matrix3x2 matrix = rotate * scale; // Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor Rectangle srcBounds = blend.Bounds(); Rectangle destBounds = TransformHelpers.GetTransformedBoundingRectangle(srcBounds, matrix); Matrix3x2 centeredMatrix = TransformHelpers.GetCenteredTransformMatrix(srcBounds, destBounds, matrix); // We pass a new rectangle here based on the dest bounds since we've offset the matrix blend.Mutate(x => x.Transform( centeredMatrix, KnownResamplers.Bicubic, new Rectangle(0, 0, destBounds.Width, destBounds.Height))); var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2); image.Mutate(x => x.DrawImage(blend, mode, .75F, position)); image.DebugSave(provider, new[] { "Transformed" }); } }
public void DrawBlendedValues_transparent <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (var img = provider.GetImage()) { var scaleX = (img.Width / 100); var scaleY = (img.Height / 100); img.Mutate(x => x.Fill(NamedColors <TPixel> .DarkBlue, new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY))); img.Mutate(x => x.Fill(NamedColors <TPixel> .HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true) { BlenderMode = mode })); img.Mutate(x => x.Fill(NamedColors <TPixel> .Transparent, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true) { BlenderMode = mode })); img.DebugSave(provider, new { mode }); } }
public void DrawBlendedValues_doldidEllips <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (var img = provider.GetImage()) { var scaleX = (img.Width / 100); var scaleY = (img.Height / 100); img.Mutate(x => x.Fill(NamedColors <TPixel> .DarkBlue, new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY))); img.Mutate(x => x.Fill(new GraphicsOptions(true) { BlenderMode = mode }, NamedColors <TPixel> .Black, new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY))); img.DebugSave(provider, new { mode }); } }
public void DrawBlendedValues_transparent50Percent <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode) where TPixel : struct, IPixel <TPixel> { using (var img = provider.GetImage()) { var scaleX = (img.Width / 100); var scaleY = (img.Height / 100); img.Mutate(x => x.Fill(NamedColors <TPixel> .DarkBlue, new Rectangle(0 * scaleX, 40, 100 * scaleX, 20 * scaleY))); img.Mutate(x => x.Fill(new GraphicsOptions(true) { BlenderMode = mode }, NamedColors <TPixel> .HotPink, new Rectangle(20 * scaleX, 0, 30 * scaleX, 100 * scaleY))); var c = NamedColors <TPixel> .Red.ToVector4(); c.W *= 0.5f; TPixel pixel = default(TPixel); pixel.PackFromVector4(c); img.Mutate(x => x.Fill(new GraphicsOptions(true) { BlenderMode = mode }, pixel, new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY))); img.DebugSave(provider, new { mode }); } }
private static void VerifyImage <TPixel>(TestImageProvider <TPixel> provider, PixelBlenderMode mode, Image <TPixel> img) where TPixel : struct, IPixel <TPixel> { img.DebugSave( provider, new { mode }, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); var comparer = ImageComparer.TolerantPercentage(0.01f, 3); img.CompareFirstFrameToReferenceOutput(comparer, provider, new { mode }, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); }
/// <summary> /// Draws the given image together with the current one by blending their pixels. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="source">The image this method extends.</param> /// <param name="image">The image to blend with the currently processing image.</param> /// <param name="blender">The blending mode.</param> /// <param name="percent">The opacity of the image image to blend. Must be between 0 and 1.</param> /// <returns>The <see cref="Image{TPixel}"/>.</returns> public static IImageProcessingContext <TPixel> Blend <TPixel>(this IImageProcessingContext <TPixel> source, Image <TPixel> image, PixelBlenderMode blender, float percent) where TPixel : struct, IPixel <TPixel> { GraphicsOptions options = GraphicsOptions.Default; options.BlendPercentage = percent; options.BlenderMode = blender; return(DrawImage(source, image, default(Size), default(Point), options)); }