Skip to content

Commit

Permalink
Bump SixLabors.ImageSharp.Drawing from 1.0.0-unstable0421 to 1.0.0-un…
Browse files Browse the repository at this point in the history
…stable0456 (#347)

* Bump SixLabors.ImageSharp.Drawing

Bumps SixLabors.ImageSharp.Drawing from 1.0.0-unstable0421 to 1.0.0-unstable0456.

Signed-off-by: dependabot-preview[bot] <[email protected]>

* Upgrade image sharp libraries

Upgrade was complicated because we went from an nighly release to a stable.

Also fixed tests.

DrawTextSafe is also no lnger needed. I've left the stub in place in case we ever need it again.

Moved some variables to readonly fields in sobel edge detector. Approximately 50-second gain over 540 seconds.

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Anthony Truskinger <[email protected]>
  • Loading branch information
dependabot-preview[bot] and atruskie authored Aug 18, 2020
1 parent 3fd6bba commit bec695d
Show file tree
Hide file tree
Showing 60 changed files with 296 additions and 225 deletions.
2 changes: 2 additions & 0 deletions AudioAnalysis.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,11 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=flac/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=FREEBSD/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Musl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=parallelization/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pteropus/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Redirector/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=resampled/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Roboto/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Runtimes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Shntool/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=spectrograms/@EntryIndexedValue">True</s:Boolean>
Expand Down
6 changes: 3 additions & 3 deletions src/AED/AED.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.7.2" />
<PackageReference Include="MathNet.Numerics.FSharp" Version="4.11.0" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-unstable0024" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-unstable0702" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-unstable0421" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-unstable0058" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-unstable0456" />
</ItemGroup>
<ItemGroup>
<Compile Include="Util.fs" />
Expand Down
8 changes: 4 additions & 4 deletions src/Acoustics.Shared/Acoustics.Shared.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyTitle>Acoustics.Shared</AssemblyTitle>
Expand Down Expand Up @@ -31,9 +31,9 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ObjectCloner" Version="2.2.2" />
<PackageReference Include="ObjectCloner.Extensions" Version="2.0.1" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-unstable0024" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-unstable0702" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-unstable0421" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-unstable0058" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-unstable0456" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.0.3" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
<PrivateAssets>all</PrivateAssets>
Expand Down
6 changes: 3 additions & 3 deletions src/Acoustics.Shared/ImageSharp/DeltaImageProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace Acoustics.Shared.ImageSharp
using SixLabors.ImageSharp.Processing.Processors;

public class DeltaImageProcessor<TPixelBg, TPixelFg> : ImageProcessor<TPixelBg>
where TPixelBg : struct, IPixel<TPixelBg>
where TPixelFg : struct, IPixel<TPixelFg>
where TPixelBg : unmanaged, IPixel<TPixelBg>
where TPixelFg : unmanaged, IPixel<TPixelFg>
{
public DeltaImageProcessor(
Configuration configuration,
Expand Down Expand Up @@ -44,7 +44,7 @@ protected override void OnFrameApply(ImageFrame<TPixelBg> source)
this.Configuration,
maxWidth);

ParallelRowIterator.IterateRows(this.Configuration, this.SourceRectangle, operation);
ParallelRowIterator.IterateRowIntervals(this.Configuration, this.SourceRectangle, in operation);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Acoustics.Shared.ImageSharp
using SixLabors.ImageSharp.Processing.Processors;

public class DeltaImageProcessor<TPixelFg> : IImageProcessor
where TPixelFg : struct, IPixel<TPixelFg>
where TPixelFg : unmanaged, IPixel<TPixelFg>
{

/// <summary>
Expand All @@ -25,7 +25,7 @@ public DeltaImageProcessor(
public Image<TPixelFg> Image { get; }

public IImageProcessor<TPixelBg> CreatePixelSpecificProcessor<TPixelBg>(Configuration configuration, Image<TPixelBg> source, Rectangle sourceRectangle)
where TPixelBg : struct, IPixel<TPixelBg>
where TPixelBg : unmanaged, IPixel<TPixelBg>
{
return new DeltaImageProcessor<TPixelBg, TPixelFg>(Configuration.Default, this.Image, source, sourceRectangle);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Acoustics.Shared/ImageSharp/DeltaPixelBlender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Acoustics.Shared.ImageSharp
/// </summary>
/// <typeparam name="TPixel">The type of pixel to operate on.</typeparam>
public class DeltaPixelBlender<TPixel> : PixelBlender<TPixel>
where TPixel : struct, IPixel<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private static readonly Vector4 Middle = new Vector4(0.5f);
private static readonly Vector4 Bottom = new Vector4(0.0f);
Expand Down
45 changes: 37 additions & 8 deletions src/Acoustics.Shared/ImageSharp/Drawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Acoustics.Shared.ImageSharp
using System.Linq;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

Expand All @@ -23,32 +24,48 @@ public static class Drawing
/// <summary>
/// An open source sans-serif font produced by Google that is hopefully a good fallback for missing fonts.
/// </summary>
public const string Roboto = "Roboto";
public const string Roboto = nameof(Roboto);

/// <summary>
/// A predefined set of graphical options. Currently is equivalent to the default.
/// </summary>
public static readonly Configuration DefaultConfiguration = Configuration.Default;

/// <summary>
/// A predefined set of graphics options with parallelization disabled.
/// </summary>
public static readonly Configuration NoParallelConfiguration = new Configuration()
{
MaxDegreeOfParallelism = 1,
};

/// <summary>
/// A predefined set of graphics options that have anti-aliasing disabled.
/// </summary>
public static readonly ShapeGraphicsOptions NoAntiAlias = new ShapeGraphicsOptions()
{
BlendPercentage = 1,
Antialias = false,
ColorBlendingMode = PixelColorBlendingMode.Normal,
AntialiasSubpixelDepth = 0,
GraphicsOptions = new GraphicsOptions()
{
Antialias = false,
BlendPercentage = 1,
ColorBlendingMode = PixelColorBlendingMode.Normal,
AntialiasSubpixelDepth = 0,
},

//IntersectionRule = IntersectionRule.OddEven,
};

/// <summary>
/// A predefined set of options for rendering text. Currently is equivalent to the default.
/// </summary>
public static readonly TextGraphicsOptions TextOptions = new TextGraphicsOptions()
{
// noop currently
};

internal const string Tahoma = "Tahoma";
internal const string Tahoma = nameof(Tahoma);

internal const string Arial = "Arial";
internal const string Arial = nameof(Arial);

/// <summary>
/// Fonts bundled with AP.exe.
Expand Down Expand Up @@ -138,11 +155,23 @@ public static Image<Rgb24> NewImage(int width, int height, Color fill)
}

public static Image<T> NewImage<T>(int width, int height, Color fill)
where T : struct, IPixel<T>
where T : unmanaged, IPixel<T>
{
return new Image<T>(DefaultConfiguration, width, height, fill.ToPixel<T>());
}

/// <summary>
/// Measures the placement of each character in a rendered string of text.
/// </summary>
public static GlyphMetric[] MeasureCharacters(string text, Font font, PointF location)
{
var rendererOptions = new RendererOptions(font, location);

TextMeasurer.TryMeasureCharacterBounds(text, rendererOptions, out var characterBounds);
//font.Instance.
return characterBounds;
}

/// <summary>
/// A specialized class the deals with drawing graphics without anti-aliasing.
/// It deals with two issues:
Expand Down
99 changes: 44 additions & 55 deletions src/Acoustics.Shared/ImageSharp/ImageSharpExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ namespace SixLabors.ImageSharp
using Acoustics.Shared.ImageSharp;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

using ApDrawing = Acoustics.Shared.ImageSharp.Drawing;

/// <summary>
/// Image extension methods.
/// </summary>
Expand Down Expand Up @@ -200,9 +204,9 @@ public static void DrawImage(
1.0f));
}

public static Drawing.NoAA NoAA(this IImageProcessingContext context)
public static ApDrawing.NoAA NoAA(this IImageProcessingContext context)
{
return new Drawing.NoAA(context);
return new ApDrawing.NoAA(context);
}

public static void DrawLine(this IImageProcessingContext context, Pen pen, int x1, int y1, int x2, int y2)
Expand All @@ -216,17 +220,24 @@ public static void DrawRectangle(this IImageProcessingContext context, Pen pen,
context.Draw(pen, r);
}

/// <summary>
/// Fill a rectangle with a brush.
/// </summary>
/// <remarks>
/// Will short-circuit return if height or width less than or equal to zero.
/// This is a "safer" operation.
/// </remarks>
public static void FillRectangle(this IImageProcessingContext context, IBrush brush, int x, int y, int width, int height)
{
if (height <= 0 || width <= 0)
{
return;
}

var r = new RectangleF(x, y, width, height);
context.Fill(brush, r);
}

public static void Clear(this IImageProcessingContext context, Color color)
{
context.Fill(color);
}

/// <summary>
/// Fills a rectangle with color that blends with the background.
/// If the given <paramref name="brush"/> contains an alpha component,
Expand All @@ -243,15 +254,15 @@ public static void Clear(this IImageProcessingContext context, Color color)
public static void FillWithBlend(this IImageProcessingContext context, IBrush brush, params IPath[] paths)
{
const float Opaque = 1f;
var options = new GraphicsOptions();
var options = new ShapeGraphicsOptions();

if (brush is SolidBrush s)
{
var alpha = ((Vector4)s.Color).W;
if (alpha != Opaque)
{
// move opacity from color to graphics layer
options.BlendPercentage = alpha;
options.GraphicsOptions.BlendPercentage = alpha;
brush = new SolidBrush(s.Color.WithAlpha(1));
}
}
Expand All @@ -266,7 +277,7 @@ public static void FillWithBlend(this IImageProcessingContext context, IBrush br
}
else
{
context.Fill(options, brush);
context.Fill(options.GraphicsOptions, brush);
}
}

Expand Down Expand Up @@ -322,7 +333,7 @@ public static float GetBrightness(this Rgb24 pixel)
}

public static void Save<T>(this Image<T> image, FileInfo path)
where T : struct, IPixel<T>
where T : unmanaged, IPixel<T>
{
image.Save(path.ToString());
}
Expand Down Expand Up @@ -362,57 +373,35 @@ public static RectangleF AsRect(this FontRectangle rectangle)
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}

public static void DrawTextSafe(this IImageProcessingContext context, string text, Font font, Color color, PointF location)
/// <summary>
/// Draws text onto an image.
/// </summary>
/// <remarks>
/// Historically this method drew a subset of glyphs if the text was located to the left
/// of the image (i.e. with a negative x coordinate).
/// </remarks>
/// <param name="context"></param>
/// <param name="text"></param>
/// <param name="font"></param>
/// <param name="color"></param>
/// <param name="location"></param>
/// <param name="textOptions"></param>
public static void DrawTextSafe(this IImageProcessingContext context, string text, Font font, Color color, PointF location, TextGraphicsOptions textOptions = null)
{
if (text.IsNullOrEmpty())
{
return;
}

textOptions ??= ApDrawing.TextOptions;

// check to see if text overlaps with image
var destArea = new RectangleF(PointF.Empty, context.GetCurrentSize());
var rendererOptions = new RendererOptions(font, location);
var textArea = TextMeasurer.MeasureBounds(text, rendererOptions);
if (destArea.IntersectsWith(textArea.AsRect()))
{
if (textArea.X < 0)
{
// TODO BUG: see https://github.com/SixLabors/ImageSharp.Drawing/issues/30
// to get around the bug, we measure each character, and then trim them from the
// start of the text, move the location right by the width of the trimmed character
// and continue until we're in a spot that does not trigger the bug;
int trim = 0;
float firstSafeCharLeft = 0;
if (TextMeasurer.TryMeasureCharacterBounds(text, rendererOptions, out var characterBounds))
{
foreach (var characterBound in characterBounds)
{
// magic value found empirically, does not seem to trigger bug when first char less
// than offset equal to char size
var magicLimit = 0 - ((int)font.Size / 2);
if (characterBound.Bounds.X > magicLimit)
{
// width of chars don't take into account kerning (spacing between chars).
// so we use the Left of the first value that is within our sfety margin instead
firstSafeCharLeft = characterBound.Bounds.Left;
break;
}

trim++;
}
}
else
{
throw new NotSupportedException("Due to a bug with ImageSharp this text cannot be rendered");
}

var safeLocation = new PointF(firstSafeCharLeft, location.Y);
context.DrawText(Drawing.TextOptions, text[trim..], font, color, safeLocation);
}
else
{
context.DrawText(Drawing.TextOptions, text, font, color, location);
}
context.DrawText(textOptions, text, font, color, location);
}
}

Expand All @@ -422,7 +411,7 @@ public static void DrawVerticalText(this IImageProcessingContext context, string
var image = new Image<Rgba32>(Configuration.Default, (int)(width + 1), (int)(height + 1), Color.Transparent);

image.Mutate(x => x
.DrawText(Drawing.TextOptions, text, font, color, new PointF(0, 0))
.DrawText(ApDrawing.TextOptions, text, font, color, new PointF(0, 0))
.Rotate(-90));

context.DrawImage(image, location, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.SrcAtop, 1);
Expand All @@ -441,7 +430,7 @@ public static void DrawVerticalText(this IImageProcessingContext context, string
/// Cropped image.
/// </returns>
public static Image<T> Crop<T>(this Image<T> source, Rectangle crop)
where T : struct, IPixel<T> => source.Clone(x => x.Crop(crop));
where T : unmanaged, IPixel<T> => source.Clone(x => x.Crop(crop));

/// <summary>
/// Crop an image using a <paramref name="crop"/> Rectangle.
Expand All @@ -457,7 +446,7 @@ public static Image<T> Crop<T>(this Image<T> source, Rectangle crop)
/// Cropped image.
/// </returns>
public static Image<T> CropIntersection<T>(this Image<T> source, Rectangle crop)
where T : struct, IPixel<T>
where T : unmanaged, IPixel<T>
{
var intersection = Rectangle.Intersect(crop, source.Bounds());

Expand All @@ -478,7 +467,7 @@ public static Image<T> CropIntersection<T>(this Image<T> source, Rectangle crop)
/// Cropped image.
/// </returns>
public static Image<T> CropInverse<T>(this Image<T> source, Rectangle crop)
where T : struct, IPixel<T>
where T : unmanaged, IPixel<T>
{
var result = new Image<T>(crop.Width, crop.Height);

Expand All @@ -494,7 +483,7 @@ public static Image<T> CropInverse<T>(this Image<T> source, Rectangle crop)
}

public static void RotateFlip<T>(this Image<T> image, RotateFlipType operation)
where T : struct, IPixel<T>
where T : unmanaged, IPixel<T>
{
RotateMode r;
FlipMode f;
Expand Down
Loading

0 comments on commit bec695d

Please sign in to comment.