Skip to content

Commit

Permalink
Merge pull request SixLabors#904 from SixLabors/af/non-generic-image-…
Browse files Browse the repository at this point in the history
…baseclass

Introduce a non-generic Image base class
  • Loading branch information
antonfirsov committed May 10, 2019
2 parents 859fd80 + e20a3f2 commit ba2de68
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 48 deletions.
2 changes: 2 additions & 0 deletions src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

<VersionPrefix Condition="$(packageversion) != ''">$(packageversion)</VersionPrefix>
<VersionPrefix Condition="$(packageversion) == ''">0.0.1</VersionPrefix>

<TargetFrameworks>netcoreapp2.1;netstandard1.3;netstandard2.0</TargetFrameworks>

<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
16 changes: 14 additions & 2 deletions tests/ImageSharp.Tests/BaseImageOperationsExtensionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors;
using SixLabors.Primitives;
using Xunit;

Expand Down Expand Up @@ -33,7 +34,12 @@ public T Verify<T>(int index = 0)

FakeImageOperationsProvider.FakeImageOperations<Rgba32>.AppliedOperation operation = this.internalOperations.Applied[index];

return Assert.IsType<T>(operation.Processor);
if (operation.NonGenericProcessor != null)
{
return Assert.IsType<T>(operation.NonGenericProcessor);
}

return Assert.IsType<T>(operation.GenericProcessor);
}

public T Verify<T>(Rectangle rect, int index = 0)
Expand All @@ -43,7 +49,13 @@ public T Verify<T>(Rectangle rect, int index = 0)
FakeImageOperationsProvider.FakeImageOperations<Rgba32>.AppliedOperation operation = this.internalOperations.Applied[index];

Assert.Equal(rect, operation.Rectangle);
return Assert.IsType<T>(operation.Processor);

if (operation.NonGenericProcessor != null)
{
return Assert.IsType<T>(operation.NonGenericProcessor);
}

return Assert.IsType<T>(operation.GenericProcessor);
}
}
}
3 changes: 2 additions & 1 deletion tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public void ImageShouldDrawTransformedImage<TPixel>(TestImageProvider<TPixel> pr
.AppendTranslation(new PointF(10, 10));

// Apply a background color so we can see the translation.
blend.Mutate(x => x.Transform(builder).BackgroundColor(NamedColors<TPixel>.HotPink));
blend.Mutate(x => x.Transform(builder));
blend.Mutate(x => x.BackgroundColor(NamedColors<TPixel>.HotPink));

// Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor
var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2);
Expand Down
4 changes: 2 additions & 2 deletions tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void ImageShouldRecolorYellowToHotPink()

foreach (TestFile file in Files)
{
using (Image<Rgba32> image = file.CreateImage())
using (Image<Rgba32> image = file.CreateRgba32Image())
{
image.Mutate(x => x.Fill(brush));
image.Save($"{path}/{file.FileName}");
Expand All @@ -36,7 +36,7 @@ public void ImageShouldRecolorYellowToHotPinkInARectangle()

foreach (TestFile file in Files)
{
using (Image<Rgba32> image = file.CreateImage())
using (Image<Rgba32> image = file.CreateRgba32Image())
{
int imageHeight = image.Height;
image.Mutate(x => x.Fill(brush, new Rectangle(0, imageHeight / 2 - imageHeight / 4, image.Width, imageHeight / 2)));
Expand Down
2 changes: 1 addition & 1 deletion tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void ImageShouldBeOverlayedByFilledPolygonImage()
new Vector2(50, 300)
};

using (Image<Rgba32> brushImage = TestFile.Create(TestImages.Bmp.Car).CreateImage())
using (Image<Rgba32> brushImage = TestFile.Create(TestImages.Bmp.Car).CreateRgba32Image())
using (var image = new Image<Rgba32>(500, 500))
{
var brush = new ImageBrush<Rgba32>(brushImage);
Expand Down
27 changes: 24 additions & 3 deletions tests/ImageSharp.Tests/FakeImageOperationsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,30 @@ public Size GetCurrentSize()
return this.Source.Size();
}

public IImageProcessingContext ApplyProcessor(IImageProcessor processor, Rectangle rectangle)
{
this.Applied.Add(new AppliedOperation()
{
Rectangle = rectangle,
NonGenericProcessor = processor
});
return this;
}

public IImageProcessingContext ApplyProcessor(IImageProcessor processor)
{
this.Applied.Add(new AppliedOperation()
{
NonGenericProcessor = processor
});
return this;
}

public IImageProcessingContext<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle)
{
this.Applied.Add(new AppliedOperation
{
Processor = processor,
GenericProcessor = processor,
Rectangle = rectangle
});
return this;
Expand All @@ -81,15 +100,17 @@ public IImageProcessingContext<TPixel> ApplyProcessor(IImageProcessor<TPixel> pr
{
this.Applied.Add(new AppliedOperation
{
Processor = processor
GenericProcessor = processor
});
return this;
}

public struct AppliedOperation
{
public Rectangle? Rectangle { get; set; }
public IImageProcessor<TPixel> Processor { get; set; }
public IImageProcessor<TPixel> GenericProcessor { get; set; }

public IImageProcessor NonGenericProcessor { get; set; }
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions tests/ImageSharp.Tests/ImageOperationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void MutateCallsImageOperationsProvider_Func_OriginalImage()
this.image.Mutate(x => x.ApplyProcessor(this.processor));

Assert.True(this.provider.HasCreated(this.image));
Assert.Contains(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.Processor));
Assert.Contains(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.GenericProcessor));
}

[Fact]
Expand All @@ -50,7 +50,7 @@ public void MutateCallsImageOperationsProvider_ListOfProcessors_OriginalImage()
this.image.Mutate(this.processor);

Assert.True(this.provider.HasCreated(this.image));
Assert.Contains(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.Processor));
Assert.Contains(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.GenericProcessor));
}

[Fact]
Expand All @@ -59,7 +59,7 @@ public void CloneCallsImageOperationsProvider_Func_WithDuplicateImage()
Image<Rgba32> returned = this.image.Clone(x => x.ApplyProcessor(this.processor));

Assert.True(this.provider.HasCreated(returned));
Assert.Contains(this.processor, this.provider.AppliedOperations(returned).Select(x => x.Processor));
Assert.Contains(this.processor, this.provider.AppliedOperations(returned).Select(x => x.GenericProcessor));
}

[Fact]
Expand All @@ -68,31 +68,31 @@ public void CloneCallsImageOperationsProvider_ListOfProcessors_WithDuplicateImag
Image<Rgba32> returned = this.image.Clone(this.processor);

Assert.True(this.provider.HasCreated(returned));
Assert.Contains(this.processor, this.provider.AppliedOperations(returned).Select(x => x.Processor));
Assert.Contains(this.processor, this.provider.AppliedOperations(returned).Select(x => x.GenericProcessor));
}

[Fact]
public void CloneCallsImageOperationsProvider_Func_NotOnOrigional()
{
Image<Rgba32> returned = this.image.Clone(x => x.ApplyProcessor(this.processor));
Assert.False(this.provider.HasCreated(this.image));
Assert.DoesNotContain(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.Processor));
Assert.DoesNotContain(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.GenericProcessor));
}

[Fact]
public void CloneCallsImageOperationsProvider_ListOfProcessors_NotOnOrigional()
{
Image<Rgba32> returned = this.image.Clone(this.processor);
Assert.False(this.provider.HasCreated(this.image));
Assert.DoesNotContain(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.Processor));
Assert.DoesNotContain(this.processor, this.provider.AppliedOperations(this.image).Select(x => x.GenericProcessor));
}

[Fact]
public void ApplyProcessors_ListOfProcessors_AppliesAllProcessorsToOperation()
{
var operations = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(null, false);
operations.ApplyProcessors(this.processor);
Assert.Contains(this.processor, operations.Applied.Select(x => x.Processor));
Assert.Contains(this.processor, operations.Applied.Select(x => x.GenericProcessor));
}

public void Dispose() => this.image.Dispose();
Expand Down
6 changes: 3 additions & 3 deletions tests/ImageSharp.Tests/TestFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public string GetFileNameWithoutExtension(object value)
/// <returns>
/// The <see cref="ImageSharp.Image"/>.
/// </returns>
public Image<Rgba32> CreateImage()
public Image<Rgba32> CreateRgba32Image()
{
return this.Image.Clone();
}
Expand All @@ -145,9 +145,9 @@ public Image<Rgba32> CreateImage()
/// <returns>
/// The <see cref="ImageSharp.Image"/>.
/// </returns>
public Image<Rgba32> CreateImage(IImageDecoder decoder)
public Image<Rgba32> CreateRgba32Image(IImageDecoder decoder)
{
return ImageSharp.Image.Load(this.Image.GetConfiguration(), this.Bytes, decoder);
return ImageSharp.Image.Load<Rgba32>(this.Image.GetConfiguration(), this.Bytes, decoder);
}
}
}
31 changes: 12 additions & 19 deletions tests/ImageSharp.Tests/TestFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,24 @@ namespace SixLabors.ImageSharp.Tests
/// </summary>
public class TestFileSystem : ImageSharp.IO.IFileSystem
{

public static TestFileSystem Global { get; } = new TestFileSystem();

public static void RegisterGlobalTestFormat()
{
Configuration.Default.FileSystem = Global;
}

Dictionary<string, Stream> fileSystem = new Dictionary<string, Stream>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, Stream> fileSystem = new Dictionary<string, Stream>(StringComparer.OrdinalIgnoreCase);

public void AddFile(string path, Stream data)
{
fileSystem.Add(path, data);
lock (this.fileSystem)
{
this.fileSystem.Add(path, data);
}
}

public Stream Create(string path)
{
// if we have injected a fake file use it instead
lock (fileSystem)
lock (this.fileSystem)
{
if (fileSystem.ContainsKey(path))
if (this.fileSystem.ContainsKey(path))
{
Stream stream = fileSystem[path];
Stream stream = this.fileSystem[path];
stream.Position = 0;
return stream;
}
Expand All @@ -43,15 +38,14 @@ public Stream Create(string path)
return File.Create(path);
}


public Stream OpenRead(string path)
{
// if we have injected a fake file use it instead
lock (fileSystem)
lock (this.fileSystem)
{
if (fileSystem.ContainsKey(path))
if (this.fileSystem.ContainsKey(path))
{
Stream stream = fileSystem[path];
Stream stream = this.fileSystem[path];
stream.Position = 0;
return stream;
}
Expand All @@ -60,5 +54,4 @@ public Stream OpenRead(string path)
return File.OpenRead(path);
}
}
}

}
Loading

0 comments on commit ba2de68

Please sign in to comment.