Skip to content

Commit

Permalink
Fix #1044
Browse files Browse the repository at this point in the history
  • Loading branch information
JimBobSquarePants committed Nov 8, 2019
1 parent f7eed91 commit ff023b8
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
8 changes: 3 additions & 5 deletions src/ImageSharp.Drawing/Processing/GradientBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0.

using System;

using System.Numerics;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;

Expand Down Expand Up @@ -120,10 +120,8 @@ protected GradientBrushApplicator(
float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / (to.Ratio - from.Ratio);

// TODO: this should be changeble for different gradienting functions.
// TODO: Why not use Blender property?
return PixelOperations<TPixel>
.Instance.GetPixelBlender(PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.SrcOver)
.Blend(from.Color.ToPixel<TPixel>(), to.Color.ToPixel<TPixel>(), onLocalGradient);
// TODO: Is the comment above still relevent?

This comment has been minimized.

Copy link
@jongleur1983

jongleur1983 Nov 8, 2019

Contributor

The comment above is relevant if an only if we want to support different Gradienting "styles" some time in future.
I'd delete it.
In general Gradients from colorA to colorB can have different styles, e.g. gradienting around the color-wheel (clockwise, counter-clockwise), gradienting in a straight line in the color cube or something else.
A sample for that can be seen in Gimp, that has the following options (condensed to those relevant for ImageSharp Gradients):
image

Translated to English:

  1. Foreground to Background - hard edge
  2. Foreground to Background - HSV color counter-clockwise
  3. Foreground to background - HSV color clockwise
  4. Foreground to background - RGB

Option 3 and 4 don't differ on the red-to-yellow example, but do on green-to-red:
image

When I initially implemented the GradientBrushes I had those in mind when writing the comment above, but perhaps I should write a feature ticket instead and we should remove the comment here.

This comment has been minimized.

Copy link
@JimBobSquarePants

JimBobSquarePants Nov 9, 2019

Author Member

Ah thanks, yep that makes sense! 👍

This comment has been minimized.

Copy link
@jongleur1983

jongleur1983 Nov 12, 2019

Contributor

opened as a feature request #1052

return new Color(Vector4.Lerp((Vector4)from.Color, (Vector4)to.Color, onLocalGradient)).ToPixel<TPixel>();
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ImageSharp/ImageSharp.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
Expand Down Expand Up @@ -119,7 +119,7 @@
</ItemGroup>

<ItemGroup>
<!--<InternalsVisibleTo Include="SixLabors.ImageSharp.Drawing" />-->
<InternalsVisibleTo Include="SixLabors.ImageSharp.Drawing" />
</ItemGroup>

<ItemGroup>
Expand Down
44 changes: 42 additions & 2 deletions tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System;
Expand All @@ -16,6 +16,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using SixLabors.Shapes;

[GroupOutput("Drawing/GradientBrushes")]
public class FillLinearGradientBrushTests
Expand Down Expand Up @@ -392,5 +394,43 @@ public void MultiplePointGradients<TPixel>(
false,
false);
}

[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32)]
public void GradientsWithTransparencyOnExistingBackground<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
provider.VerifyOperation(
image =>
{
image.Mutate(i => i.Fill(Color.Red));
image.Mutate(ApplyGloss);

});

void ApplyGloss(IImageProcessingContext ctx)
{
Size size = ctx.GetCurrentSize();
IPathCollection glossPath = BuildGloss(size.Width, size.Height);
var graphicsOptions = new GraphicsOptions(true)
{
ColorBlendingMode = PixelColorBlendingMode.Normal,
AlphaCompositionMode = PixelAlphaCompositionMode.SrcAtop
};
var linearGradientBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, size.Height / 2), GradientRepetitionMode.Repeat, new ColorStop(0, Color.White.WithAlpha(0.5f)), new ColorStop(1, Color.White.WithAlpha(0.25f)));
ctx.Fill(graphicsOptions, linearGradientBrush, glossPath);
}

IPathCollection BuildGloss(int imageWidth, int imageHeight)
{
var pathBuilder = new PathBuilder();
pathBuilder.AddLine(new PointF(0, 0), new PointF(imageWidth, 0));
pathBuilder.AddLine(new PointF(imageWidth, 0), new PointF(imageWidth, imageHeight * 0.4f));
pathBuilder.AddBezier(new PointF(imageWidth, imageHeight * 0.4f), new PointF(imageWidth / 2, imageHeight * 0.6f), new PointF(0, imageHeight * 0.4f));
pathBuilder.CloseFigure();
return new PathCollection(pathBuilder.Build());
}
}

}
}
}

0 comments on commit ff023b8

Please sign in to comment.