diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
index 7311a53da..3285e75a7 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
@@ -109,28 +109,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
return false;
}
- if (this.options.ColorBlendingMode != PixelColorBlendingMode.Normal)
- {
- return false;
- }
-
- if (this.options.AlphaCompositionMode != PixelAlphaCompositionMode.SrcOver &&
- this.options.AlphaCompositionMode != PixelAlphaCompositionMode.Src)
- {
- return false;
- }
-
- if (this.options.BlendPercentage != 1f)
- {
- return false;
- }
-
- if (solidBrush.Color.ToVector4().W != 1f)
- {
- return false;
- }
-
- return true;
+ return this.options.IsOpaqueColorWithoutBlending(solidBrush.Color);
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/GraphicsOptions.cs b/src/ImageSharp/GraphicsOptions.cs
index 260fc2d75..2d20c1773 100644
--- a/src/ImageSharp/GraphicsOptions.cs
+++ b/src/ImageSharp/GraphicsOptions.cs
@@ -36,6 +36,57 @@ namespace SixLabors.ImageSharp
this.blendPercentage = 1;
this.antialiasSubpixelDepth = 16;
this.antialias = enableAntialiasing;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// If set to true [enable antialiasing].
+ /// blending percentage to apply to the drawing operation
+ public GraphicsOptions(bool enableAntialiasing, float opacity)
+ {
+ Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
+
+ this.colorBlendingMode = PixelColorBlendingMode.Normal;
+ this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver;
+ this.blendPercentage = opacity;
+ this.antialiasSubpixelDepth = 16;
+ this.antialias = enableAntialiasing;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// If set to true [enable antialiasing].
+ /// blending percentage to apply to the drawing operation
+ /// color blending mode to apply to the drawing operation
+ public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, float opacity)
+ {
+ Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
+
+ this.colorBlendingMode = blending;
+ this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver;
+ this.blendPercentage = opacity;
+ this.antialiasSubpixelDepth = 16;
+ this.antialias = enableAntialiasing;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// If set to true [enable antialiasing].
+ /// blending percentage to apply to the drawing operation
+ /// color blending mode to apply to the drawing operation
+ /// alpha composition mode to apply to the drawing operation
+ public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, PixelAlphaCompositionMode composition, float opacity)
+ {
+ Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
+
+ this.colorBlendingMode = blending;
+ this.alphaCompositionMode = composition;
+ this.blendPercentage = opacity;
+ this.antialiasSubpixelDepth = 16;
+ this.antialias = enableAntialiasing;
}
///
@@ -85,6 +136,44 @@ namespace SixLabors.ImageSharp
{
get => this.alphaCompositionMode;
set => this.alphaCompositionMode = value;
+ }
+
+ ///
+ /// Evaluates if a given SOURCE color can completely replace a BACKDROP color given the current blending and composition settings.
+ ///
+ /// The pixel format
+ /// the color
+ /// true if the color can be considered opaque
+ ///
+ /// Blending and composition is an expensive operation, in some cases, like
+ /// filling with a solid color, the blending can be avoided by a plain color replacement.
+ /// This method can be useful for such processors to select the fast path.
+ ///
+ internal bool IsOpaqueColorWithoutBlending(TPixel color)
+ where TPixel : struct, IPixel
+ {
+ if (this.ColorBlendingMode != PixelColorBlendingMode.Normal)
+ {
+ return false;
+ }
+
+ if (this.AlphaCompositionMode != PixelAlphaCompositionMode.SrcOver &&
+ this.AlphaCompositionMode != PixelAlphaCompositionMode.Src)
+ {
+ return false;
+ }
+
+ if (this.BlendPercentage != 1f)
+ {
+ return false;
+ }
+
+ if (color.ToVector4().W != 1f)
+ {
+ return false;
+ }
+
+ return true;
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs
index e084379ba..9e41fd94f 100644
--- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs
+++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs
@@ -88,6 +88,17 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
where TPixel : struct, IPixel
{
Assert.NotNull(PixelOperations.Instance);
+ }
+
+ [Fact]
+ public void IsOpaqueColor()
+ {
+ Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red));
+
+ Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red));
+ Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Transparent));
+ Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red));
+ Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal,PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red));
}
}