Skip to content

Commit fb47d02

Browse files
committed
Merge remote-tracking branch 'origin/master' into GradientBrush
2 parents 692bc4a + e12f053 commit fb47d02

File tree

4 files changed

+284
-137
lines changed

4 files changed

+284
-137
lines changed

src/ImageSharp.Drawing/Processing/Drawing/Processors/FillProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle source
6868
sourceRectangle,
6969
this.options))
7070
{
71-
amount.Span.Fill(this.options.BlendPercentage);
71+
amount.Span.Fill(1f);
7272

7373
Parallel.For(
7474
minY,

tests/ImageSharp.Tests/Drawing/BlendedShapes.cs

Lines changed: 0 additions & 92 deletions
This file was deleted.
Lines changed: 129 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,164 @@
11
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

4-
using System.Numerics;
54
using SixLabors.ImageSharp.PixelFormats;
65
using SixLabors.ImageSharp.Processing;
76
using SixLabors.ImageSharp.Processing.Drawing;
8-
using SixLabors.ImageSharp.Processing.Overlays;
7+
using SixLabors.ImageSharp.Primitives;
8+
using SixLabors.ImageSharp.Processing.Drawing.Brushes;
9+
using SixLabors.Shapes;
910
using Xunit;
11+
// ReSharper disable InconsistentNaming
1012

1113
namespace SixLabors.ImageSharp.Tests.Drawing
1214
{
13-
public class FillSolidBrushTests : FileTestBase
15+
16+
17+
[GroupOutput("Drawing")]
18+
public class FillSolidBrushTests
1419
{
15-
[Fact]
16-
public void ImageShouldBeFloodFilledWithColorOnDefaultBackground()
20+
[Theory]
21+
[WithBlankImages(1, 1, PixelTypes.Rgba32)]
22+
[WithBlankImages(7, 4, PixelTypes.Rgba32)]
23+
[WithBlankImages(16, 7, PixelTypes.Rgba32)]
24+
[WithBlankImages(33, 32, PixelTypes.Rgba32)]
25+
[WithBlankImages(400, 500, PixelTypes.Rgba32)]
26+
public void DoesNotDependOnSize<TPixel>(TestImageProvider<TPixel> provider)
27+
where TPixel : struct, IPixel<TPixel>
1728
{
18-
string path = TestEnvironment.CreateOutputDirectory("Fill", "SolidBrush");
19-
using (var image = new Image<Rgba32>(500, 500))
29+
using (Image<TPixel> image = provider.GetImage())
2030
{
21-
image.Mutate(x => x.Fill(Rgba32.HotPink));
22-
image.Save($"{path}/DefaultBack.png");
23-
24-
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
25-
{
26-
Assert.Equal(Rgba32.HotPink, sourcePixels[9, 9]);
31+
TPixel color = NamedColors<TPixel>.HotPink;
32+
image.Mutate(c => c.Fill(color));
2733

28-
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
29-
}
34+
image.DebugSave(provider, appendPixelTypeToFileName: false);
35+
image.ComparePixelBufferTo(color);
3036
}
3137
}
3238

33-
[Fact]
34-
public void ImageShouldBeFloodFilledWithColor()
39+
[Theory]
40+
[WithBlankImages(16, 16, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector)]
41+
public void DoesNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
42+
where TPixel : struct, IPixel<TPixel>
3543
{
36-
string path = TestEnvironment.CreateOutputDirectory("Fill", "SolidBrush");
37-
using (var image = new Image<Rgba32>(500, 500))
44+
using (Image<TPixel> image = provider.GetImage())
3845
{
39-
image.Mutate(x => x
40-
.BackgroundColor(Rgba32.Blue)
41-
.Fill(Rgba32.HotPink));
42-
image.Save($"{path}/Simple.png");
46+
TPixel color = NamedColors<TPixel>.HotPink;
47+
image.Mutate(c => c.Fill(color));
4348

44-
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
45-
{
46-
Assert.Equal(Rgba32.HotPink, sourcePixels[9, 9]);
47-
48-
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
49-
}
49+
image.DebugSave(provider, appendSourceFileOrDescription: false);
50+
image.ComparePixelBufferTo(color);
5051
}
5152
}
5253

53-
[Fact]
54-
public void ImageShouldBeFloodFilledWithColorOpacity()
54+
[Theory]
55+
[WithSolidFilledImages(16, 16, "Red", PixelTypes.Rgba32, "Blue")]
56+
[WithSolidFilledImages(16, 16, "Yellow", PixelTypes.Rgba32, "Khaki")]
57+
public void WhenColorIsOpaque_OverridePreviousColor<TPixel>(TestImageProvider<TPixel> provider, string newColorName)
58+
where TPixel : struct, IPixel<TPixel>
5559
{
56-
string path = TestEnvironment.CreateOutputDirectory("Fill", "SolidBrush");
57-
using (var image = new Image<Rgba32>(500, 500))
60+
using (Image<TPixel> image = provider.GetImage())
5861
{
59-
var color = new Rgba32(Rgba32.HotPink.R, Rgba32.HotPink.G, Rgba32.HotPink.B, 150);
62+
TPixel color = TestUtils.GetPixelOfNamedColor<TPixel>(newColorName);
63+
image.Mutate(c => c.Fill(color));
64+
65+
image.DebugSave(provider, newColorName, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
66+
image.ComparePixelBufferTo(color);
67+
}
68+
}
69+
70+
public static readonly TheoryData<bool, string, float, PixelBlenderMode, float> BlendData =
71+
new TheoryData<bool, string, float, PixelBlenderMode, float>()
72+
{
73+
{ false, "Blue", 0.5f, PixelBlenderMode.Normal, 1.0f },
74+
{ false, "Blue", 1.0f, PixelBlenderMode.Normal, 0.5f },
75+
{ false, "Green", 0.5f, PixelBlenderMode.Normal, 0.3f },
76+
{ false, "HotPink", 0.8f, PixelBlenderMode.Normal, 0.8f },
77+
78+
{ false, "Blue", 0.5f, PixelBlenderMode.Multiply, 1.0f },
79+
{ false, "Blue", 1.0f, PixelBlenderMode.Multiply, 0.5f },
80+
{ false, "Green", 0.5f, PixelBlenderMode.Multiply, 0.3f },
81+
{ false, "HotPink", 0.8f, PixelBlenderMode.Multiply, 0.8f },
82+
83+
{ false, "Blue", 0.5f, PixelBlenderMode.Add, 1.0f },
84+
{ false, "Blue", 1.0f, PixelBlenderMode.Add, 0.5f },
85+
{ false, "Green", 0.5f, PixelBlenderMode.Add, 0.3f },
86+
{ false, "HotPink", 0.8f, PixelBlenderMode.Add, 0.8f },
6087

61-
image.Mutate(x => x
62-
.BackgroundColor(Rgba32.Blue)
63-
.Fill(color));
64-
image.Save($"{path}/Opacity.png");
88+
{ true, "Blue", 0.5f, PixelBlenderMode.Normal, 1.0f },
89+
{ true, "Blue", 1.0f, PixelBlenderMode.Normal, 0.5f },
90+
{ true, "Green", 0.5f, PixelBlenderMode.Normal, 0.3f },
91+
{ true, "HotPink", 0.8f, PixelBlenderMode.Normal, 0.8f },
6592

66-
//shift background color towards forground color by the opacity amount
67-
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
93+
{ true, "Blue", 0.5f, PixelBlenderMode.Multiply, 1.0f },
94+
{ true, "Blue", 1.0f, PixelBlenderMode.Multiply, 0.5f },
95+
{ true, "Green", 0.5f, PixelBlenderMode.Multiply, 0.3f },
96+
{ true, "HotPink", 0.8f, PixelBlenderMode.Multiply, 0.8f },
6897

98+
{ true, "Blue", 0.5f, PixelBlenderMode.Add, 1.0f },
99+
{ true, "Blue", 1.0f, PixelBlenderMode.Add, 0.5f },
100+
{ true, "Green", 0.5f, PixelBlenderMode.Add, 0.3f },
101+
{ true, "HotPink", 0.8f, PixelBlenderMode.Add, 0.8f },
102+
};
69103

70-
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
104+
[Theory]
105+
[WithSolidFilledImages(nameof(BlendData), 16, 16, "Red", PixelTypes.Rgba32)]
106+
public void BlendFillColorOverBackround<TPixel>(
107+
TestImageProvider<TPixel> provider,
108+
bool triggerFillRegion,
109+
string newColorName,
110+
float alpha,
111+
PixelBlenderMode blenderMode,
112+
float blendPercentage)
113+
where TPixel : struct, IPixel<TPixel>
114+
{
115+
var vec = TestUtils.GetPixelOfNamedColor<RgbaVector>(newColorName).ToVector4();
116+
vec.W = alpha;
117+
118+
TPixel fillColor = default;
119+
fillColor.PackFromVector4(vec);
120+
121+
using (Image<TPixel> image = provider.GetImage())
122+
{
123+
TPixel bgColor = image[0, 0];
124+
125+
var options = new GraphicsOptions(false)
126+
{
127+
BlenderMode = blenderMode,
128+
BlendPercentage = blendPercentage
129+
};
130+
131+
if (triggerFillRegion)
132+
{
133+
var region = new ShapeRegion(new RectangularPolygon(0, 0, 16, 16));
134+
135+
image.Mutate(c => c.Fill(options, new SolidBrush<TPixel>(fillColor), region));
136+
}
137+
else
71138
{
72-
Assert.Equal(mergedColor, sourcePixels[9, 9]);
73-
Assert.Equal(mergedColor, sourcePixels[199, 149]);
139+
image.Mutate(c => c.Fill(options, new SolidBrush<TPixel>(fillColor)));
74140
}
141+
142+
var testOutputDetails = new
143+
{
144+
triggerFillRegion = triggerFillRegion,
145+
newColorName = newColorName,
146+
alpha = alpha,
147+
blenderMode = blenderMode,
148+
blendPercentage = blendPercentage
149+
};
150+
151+
image.DebugSave(
152+
provider,
153+
testOutputDetails,
154+
appendPixelTypeToFileName: false,
155+
appendSourceFileOrDescription: false);
156+
157+
PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(blenderMode);
158+
TPixel expectedPixel = blender.Blend(bgColor, fillColor, blendPercentage);
159+
160+
image.ComparePixelBufferTo(expectedPixel);
75161
}
76162
}
77-
78163
}
79164
}

0 commit comments

Comments
 (0)