Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageSharp v4 compatibility #351

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:war
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = always_for_clarity:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:warning
dotnet_style_collection_initializer = true:warning
dotnet_style_object_initializer = true:error
dotnet_style_collection_initializer = true:error
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
Expand Down Expand Up @@ -135,9 +135,9 @@ csharp_style_prefer_null_check_over_type_check = true:warning
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules#c-style-rules
[*.{cs,csx,cake}]
# 'var' preferences
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_when_type_is_apparent = false:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_for_built_in_types = false:error
csharp_style_var_when_type_is_apparent = false:error
csharp_style_var_elsewhere = false:error
# Expression-bodied members
csharp_style_expression_bodied_methods = true:warning
csharp_style_expression_bodied_constructors = true:warning
Expand All @@ -160,7 +160,7 @@ csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:error
# "Null" checking preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
Expand All @@ -172,6 +172,8 @@ dotnet_diagnostic.IDE0063.severity = suggestion
csharp_using_directive_placement = outside_namespace:warning
# Modifier preferences
csharp_prefer_static_local_function = true:warning
# Primary constructor preferences
csharp_style_prefer_primary_constructors = false:none

##########################################
# Unnecessary Code Rules
Expand Down
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,13 @@
*.pnm filter=lfs diff=lfs merge=lfs -text
*.wbmp filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.ico filter=lfs diff=lfs merge=lfs -text
*.cur filter=lfs diff=lfs merge=lfs -text
*.ani filter=lfs diff=lfs merge=lfs -text
*.heic filter=lfs diff=lfs merge=lfs -text
*.hif filter=lfs diff=lfs merge=lfs -text
*.avif filter=lfs diff=lfs merge=lfs -text
###############################################################################
# Handle ICC files by git lfs
###############################################################################
*.icc filter=lfs diff=lfs merge=lfs -text
40 changes: 23 additions & 17 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,50 @@ jobs:
- ${{ contains(github.event.pull_request.labels.*.name, 'arch:arm32') || contains(github.event.pull_request.labels.*.name, 'arch:arm64') }}
options:
- os: ubuntu-latest
framework: net7.0
sdk: 7.0.x
framework: net9.0
sdk: 9.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
framework: net7.0
sdk: 7.0.x
framework: net9.0
sdk: 9.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: windows-latest
framework: net7.0
sdk: 7.0.x
framework: net9.0
sdk: 9.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: buildjet-4vcpu-ubuntu-2204-arm
framework: net7.0
sdk: 7.0.x
framework: net9.0
sdk: 9.0.x
sdk-preview: true
runtime: -x64
codecov: false

- os: ubuntu-latest
framework: net6.0
sdk: 6.0.x
framework: net8.0
sdk: 8.0.x
runtime: -x64
codecov: false
- os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
framework: net6.0
sdk: 6.0.x
framework: net8.0
sdk: 8.0.x
runtime: -x64
codecov: false
- os: windows-latest
framework: net6.0
sdk: 6.0.x
framework: net8.0
sdk: 8.0.x
runtime: -x64
codecov: true
codecov: false
- os: buildjet-4vcpu-ubuntu-2204-arm
framework: net8.0
sdk: 8.0.x
runtime: -x64
codecov: false
exclude:
- isARM: false
options:
Expand Down Expand Up @@ -110,14 +116,14 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x

- name: DotNet Setup Preview
if: ${{ matrix.options.sdk-preview == true }}
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
7.0.x
9.0.x

- name: DotNet Build
if: ${{ matrix.options.sdk-preview != true }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>
Expand Down
2 changes: 1 addition & 1 deletion samples/DrawShapesWithImageSharp/ImageSharpLogo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static void SaveLogo(float size, string path)
img.Mutate(i => i.Fill(colors[s], segments[s].Transform(scaler)));
}

img.Mutate(i => i.Fill(new Rgba32(0, 0, 0, 170), new ComplexPolygon(new EllipsePolygon(center, 161f), new EllipsePolygon(center, 61f)).Transform(scaler)));
img.Mutate(i => i.Fill(Color.FromPixel(new Rgba32(0, 0, 0, 170)), new ComplexPolygon(new EllipsePolygon(center, 161f), new EllipsePolygon(center, 61f)).Transform(scaler)));

string fullPath = System.IO.Path.GetFullPath(System.IO.Path.Combine("Output", path));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static bool IsOpaqueColorWithoutBlending(this GraphicsOptions options, Co
return false;
}

if (((Vector4)color).W != Opaque)
if (color.ToScaledVector4().W != Opaque)
{
return false;
}
Expand Down
14 changes: 7 additions & 7 deletions src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
<PackageTags>Image Draw Shape Path Font</PackageTags>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<Configurations>Debug;Release</Configurations>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>

<PropertyGroup>
<!--Bump to V2 prior to tagged release.-->
<MinVerMinimumMajorMinor>2.0</MinVerMinimumMajorMinor>
<!--Bump to V3 prior to tagged release.-->
<MinVerMinimumMajorMinor>3.0</MinVerMinimumMajorMinor>
</PropertyGroup>

<!-- This enables the nullable analysis and treats all nullable warnings as error-->
Expand All @@ -28,13 +29,12 @@
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
<IsTrimmable>true</IsTrimmable>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
</Otherwise>
Expand All @@ -45,8 +45,8 @@
<None Include="..\..\shared-infrastructure\branding\icons\imagesharp.drawing\sixlabors.imagesharp.drawing.128.png" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SixLabors.Fonts" Version="2.0.8" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" />
<PackageReference Include="SixLabors.Fonts" Version="2.0.9" />
<PackageReference Include="SixLabors.ImageSharp" Version="4.0.0-alpha.0.18" />
</ItemGroup>
<Import Project="..\..\shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems" Label="Shared" />
</Project>
7 changes: 5 additions & 2 deletions src/ImageSharp.Drawing/Processing/GradientBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Utilities;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;

namespace SixLabors.ImageSharp.Drawing.Processing;

Expand Down Expand Up @@ -138,7 +137,11 @@ protected GradientBrushApplicator(
float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / (to.Ratio - from.Ratio);

// TODO: This should use premultiplied vectors to avoid bad blends e.g. red -> brown <- green.
return new Color(Vector4.Lerp((Vector4)from.Color, (Vector4)to.Color, onLocalGradient)).ToPixel<TPixel>();
return Color.FromScaledVector(
Vector4.Lerp(
from.Color.ToScaledVector4(),
to.Color.ToScaledVector4(),
onLocalGradient)).ToPixel<TPixel>();
}
}

Expand Down
31 changes: 9 additions & 22 deletions src/ImageSharp.Drawing/Processing/PathGradientBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ public sealed class PathGradientBrush : Brush
/// <param name="colors">Array of colors that correspond to each point in the polygon.</param>
public PathGradientBrush(PointF[] points, Color[] colors)
{
if (points == null)
{
throw new ArgumentNullException(nameof(points));
}
ArgumentNullException.ThrowIfNull(points);

if (points.Length < 3)
{
Expand All @@ -34,10 +31,7 @@ public PathGradientBrush(PointF[] points, Color[] colors)
"There must be at least 3 lines to construct a path gradient brush.");
}

if (colors == null)
{
throw new ArgumentNullException(nameof(colors));
}
ArgumentNullException.ThrowIfNull(colors);

if (colors.Length == 0)
{
Expand Down Expand Up @@ -106,10 +100,7 @@ public override BrushApplicator<TPixel> CreateApplicator<TPixel>(

private static Color CalculateCenterColor(Color[] colors)
{
if (colors == null)
{
throw new ArgumentNullException(nameof(colors));
}
ArgumentNullException.ThrowIfNull(colors);

if (colors.Length == 0)
{
Expand All @@ -118,7 +109,7 @@ private static Color CalculateCenterColor(Color[] colors)
"One or more color is needed to construct a path gradient brush.");
}

return new Color(colors.Select(c => (Vector4)c).Aggregate((p1, p2) => p1 + p2) / colors.Length);
return Color.FromScaledVector(colors.Select(c => c.ToScaledVector4()).Aggregate((p1, p2) => p1 + p2) / colors.Length);
}

private static float DistanceBetween(Vector2 p1, Vector2 p2) => (p2 - p1).Length();
Expand Down Expand Up @@ -147,8 +138,8 @@ public Edge(Vector2 start, Vector2 end, Color startColor, Color endColor)
{
this.Start = start;
this.End = end;
this.StartColor = (Vector4)startColor;
this.EndColor = (Vector4)endColor;
this.StartColor = startColor.ToScaledVector4();
this.EndColor = endColor.ToScaledVector4();

this.length = DistanceBetween(this.End, this.Start);
}
Expand Down Expand Up @@ -236,7 +227,7 @@ public PathGradientBrushApplicator(
Vector2[] points = edges.Select(s => s.Start).ToArray();

this.center = points.Aggregate((p1, p2) => p1 + p2) / edges.Count;
this.centerColor = (Vector4)centerColor;
this.centerColor = centerColor.ToScaledVector4();
this.hasSpecialCenterColor = hasSpecialCenterColor;
this.centerPixel = centerColor.ToPixel<TPixel>();
this.maxDistance = points.Select(p => p - this.center).Max(d => d.Length());
Expand Down Expand Up @@ -272,9 +263,7 @@ public PathGradientBrushApplicator(
+ (u * this.edges[0].EndColor)
+ (v * this.edges[2].StartColor);

TPixel px = default;
px.FromScaledVector4(pointColor);
return px;
return TPixel.FromScaledVector4(pointColor);
}

Vector2 direction = Vector2.Normalize(point - this.center);
Expand All @@ -295,9 +284,7 @@ public PathGradientBrushApplicator(

Vector4 color = Vector4.Lerp(edgeColor, this.centerColor, ratio);

TPixel pixel = default;
pixel.FromScaledVector4(color);
return pixel;
return TPixel.FromScaledVector4(color);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/ImageSharp.Drawing/Processing/PatternBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public PatternBrush(Color foreColor, Color backColor, bool[,] pattern)
/// <param name="pattern">The pattern.</param>
internal PatternBrush(Color foreColor, Color backColor, in DenseMatrix<bool> pattern)
{
var foreColorVector = (Vector4)foreColor;
var backColorVector = (Vector4)backColor;
var foreColorVector = foreColor.ToScaledVector4();
var backColorVector = backColor.ToScaledVector4();
this.pattern = new DenseMatrix<Color>(pattern.Columns, pattern.Rows);
this.patternVector = new DenseMatrix<Vector4>(pattern.Columns, pattern.Rows);
for (int i = 0; i < pattern.Data.Length; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ protected override void BeginGlyph(in FontRectangle bounds, in GlyphRendererPara

/// <inheritdoc/>
public void SetColor(GlyphColor color)
=> this.currentColor = new Color(new Rgba32(color.Red, color.Green, color.Blue, color.Alpha));
=> this.currentColor = Color.FromPixel(new Rgba32(color.Red, color.Green, color.Blue, color.Alpha));

public override TextDecorations EnabledDecorations()
{
Expand Down
6 changes: 2 additions & 4 deletions src/ImageSharp.Drawing/Processing/RecolorBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,8 @@ public RecolorBrushApplicator(
this.targetColorPixel = targetColor;

// Lets hack a min max extremes for a color space by letting the IPackedPixel clamp our values to something in the correct spaces :)
var maxColor = default(TPixel);
maxColor.FromVector4(new Vector4(float.MaxValue));
var minColor = default(TPixel);
minColor.FromVector4(new Vector4(float.MinValue));
TPixel maxColor = TPixel.FromVector4(new Vector4(float.MaxValue));
TPixel minColor = TPixel.FromVector4(new Vector4(float.MinValue));
this.threshold = Vector4.DistanceSquared(maxColor.ToVector4(), minColor.ToVector4()) * threshold;
this.blenderBuffers = new ThreadLocalBlenderBuffers<TPixel>(configuration.MemoryAllocator, source.Width);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,13 @@ static void RoundY(ReadOnlySpan<PointF> vertices, Span<float> destination, float
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<float> AdvSimdShuffle(Vector128<float> a, Vector128<float> b, byte control)
{
// TODO: Review the codegen here. Might be better just looping.
#pragma warning disable CA1857 // A constant is expected for the parameter
Vector128<float> result = Vector128.Create(AdvSimd.Extract(a, (byte)(control & 0x3)));
result = AdvSimd.Insert(result, 1, AdvSimd.Extract(a, (byte)((control >> 2) & 0x3)));
result = AdvSimd.Insert(result, 2, AdvSimd.Extract(b, (byte)((control >> 4) & 0x3)));
result = AdvSimd.Insert(result, 3, AdvSimd.Extract(b, (byte)((control >> 6) & 0x3)));
#pragma warning restore CA1857 // A constant is expected for the parameter

return result;
}
Expand Down
16 changes: 10 additions & 6 deletions tests/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@
<ItemGroup>
<!-- Test Dependencies -->
<PackageReference Update="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="12.2.2" />
<PackageReference Update="Microsoft.DotNet.RemoteExecutor" Version="6.0.0-beta.21311.3" />
<PackageReference Update="Microsoft.DotNet.XUnitExtensions" Version="6.0.0-beta.21311.3" />
<PackageReference Update="Moq" Version="4.16.1" />
<!--
Do not update to 14+ yet. There's differnce in how the BMP decoder handles rounding in 16 bit images.
See https://github.com/ImageMagick/ImageMagick/commit/27a0a9c37f18af9c8d823a3ea076f600843b553c
-->
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="13.10.0" />
<PackageReference Update="Microsoft.DotNet.RemoteExecutor" Version="8.0.0-beta.23580.1" />
<PackageReference Update="Microsoft.DotNet.XUnitExtensions" Version="8.0.0-beta.23580.1" />
<PackageReference Update="Moq" Version="4.20.72" />
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="5.8.64" Condition="'$(IsOSX)'=='true'" />
<PackageReference Update="System.Drawing.Common" Version="5.0.2" />
<PackageReference Update="System.Drawing.Common" Version="6.0.0" />
<PackageReference Update="GeoJSON.Net" Version="1.2.19" />
<PackageReference Update="SkiaSharp" Version="2.80.3" />
<PackageReference Update="SkiaSharp" Version="2.88.9" />
</ItemGroup>

</Project>
Loading
Loading