Browse Source

Replace IImageEncoder

pull/2301/head
James Jackson-South 4 years ago
parent
commit
31def5c753
  1. 8
      src/ImageSharp/Advanced/AdvancedImageExtensions.cs
  2. 6
      src/ImageSharp/Advanced/AotCompilerTools.cs
  3. 32
      src/ImageSharp/Formats/IImageEncoder.cs
  4. 18
      src/ImageSharp/Formats/ImageEncoder.cs
  5. 16
      src/ImageSharp/Formats/ImageFormatManager.cs
  6. 8
      src/ImageSharp/Image.cs
  7. 18
      src/ImageSharp/ImageExtensions.cs
  8. 10
      tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
  9. 8
      tests/ImageSharp.Tests/Image/ImageSaveTests.cs
  10. 2
      tests/ImageSharp.Tests/Image/ImageTests.Save.cs
  11. 4
      tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs
  12. 2
      tests/ImageSharp.Tests/Image/ImageTests.cs
  13. 2
      tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs
  14. 2
      tests/ImageSharp.Tests/Metadata/Profiles/XMP/XmpProfileTests.cs
  15. 9
      tests/ImageSharp.Tests/TestFormat.cs
  16. 4
      tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
  17. 21
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs
  18. 8
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs
  19. 11
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  20. 4
      tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs

8
src/ImageSharp/Advanced/AdvancedImageExtensions.cs

@ -21,8 +21,8 @@ public static class AdvancedImageExtensions
/// <param name="filePath">The target file path to save the image to.</param>
/// <exception cref="ArgumentNullException">The file path is null.</exception>
/// <exception cref="NotSupportedException">No encoder available for provided path.</exception>
/// <returns>The matching <see cref="IImageEncoder"/>.</returns>
public static IImageEncoder DetectEncoder(this Image source, string filePath)
/// <returns>The matching <see cref="ImageEncoder"/>.</returns>
public static ImageEncoder DetectEncoder(this Image source, string filePath)
{
Guard.NotNull(filePath, nameof(filePath));
@ -40,13 +40,13 @@ public static class AdvancedImageExtensions
throw new NotSupportedException(sb.ToString());
}
IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
ImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
if (encoder is null)
{
StringBuilder sb = new();
sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:");
foreach (KeyValuePair<IImageFormat, IImageEncoder> enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
foreach (KeyValuePair<IImageFormat, ImageEncoder> enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
{
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine);
}

6
src/ImageSharp/Advanced/AotCompilerTools.cs

@ -230,7 +230,7 @@ internal static class AotCompilerTools
}
/// <summary>
/// This method pre-seeds the all <see cref="IImageEncoder"/> in the AoT compiler.
/// This method pre-seeds the all <see cref="ImageEncoder"/> in the AoT compiler.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
[Preserve]
@ -266,14 +266,14 @@ internal static class AotCompilerTools
}
/// <summary>
/// This method pre-seeds the <see cref="IImageEncoder"/> in the AoT compiler.
/// This method pre-seeds the <see cref="ImageEncoder"/> in the AoT compiler.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <typeparam name="TEncoder">The encoder.</typeparam>
[Preserve]
private static void AotCompileImageEncoder<TPixel, TEncoder>()
where TPixel : unmanaged, IPixel<TPixel>
where TEncoder : class, IImageEncoder
where TEncoder : ImageEncoder
{
default(TEncoder).Encode<TPixel>(default, default);
default(TEncoder).EncodeAsync<TPixel>(default, default, default);

32
src/ImageSharp/Formats/IImageEncoder.cs

@ -1,32 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats;
/// <summary>
/// Encapsulates properties and methods required for encoding an image to a stream.
/// </summary>
public interface IImageEncoder
{
/// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="image">The <see cref="Image{TPixel}"/> to encode from.</param>
/// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>;
/// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="image">The <see cref="Image{TPixel}"/> to encode from.</param>
/// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>;
}

18
src/ImageSharp/Formats/ImageEncoder.cs

@ -10,18 +10,30 @@ namespace SixLabors.ImageSharp.Formats;
/// <summary>
/// The base class for all image encoders.
/// </summary>
public abstract class ImageEncoder : IImageEncoder
public abstract class ImageEncoder
{
/// <summary>
/// Gets a value indicating whether to ignore decoded metadata when encoding.
/// </summary>
public bool SkipMetadata { get; init; }
/// <inheritdoc/>
/// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}" />.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="image">The <see cref="Image{TPixel}" /> to encode from.</param>
/// <param name="stream">The <see cref="Stream" /> to encode the image data to.</param>
public abstract void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>;
/// <inheritdoc/>
/// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}" />.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="image">The <see cref="Image{TPixel}" /> to encode from.</param>
/// <param name="stream">The <see cref="Stream" /> to encode the image data to.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <returns>A <see cref="Task" /> representing the asynchronous operation.</returns>
public abstract Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>;
}

16
src/ImageSharp/Formats/ImageFormatManager.cs

@ -17,9 +17,9 @@ public class ImageFormatManager
private static readonly object HashLock = new();
/// <summary>
/// The list of supported <see cref="IImageEncoder"/> keyed to mime types.
/// The list of supported <see cref="ImageEncoder"/> keyed to mime types.
/// </summary>
private readonly ConcurrentDictionary<IImageFormat, IImageEncoder> mimeTypeEncoders = new();
private readonly ConcurrentDictionary<IImageFormat, ImageEncoder> mimeTypeEncoders = new();
/// <summary>
/// The list of supported <see cref="ImageDecoder"/> keyed to mime types.
@ -64,9 +64,9 @@ public class ImageFormatManager
internal IEnumerable<KeyValuePair<IImageFormat, ImageDecoder>> ImageDecoders => this.mimeTypeDecoders;
/// <summary>
/// Gets the currently registered <see cref="IImageEncoder"/>s.
/// Gets the currently registered <see cref="ImageEncoder"/>s.
/// </summary>
internal IEnumerable<KeyValuePair<IImageFormat, IImageEncoder>> ImageEncoders => this.mimeTypeEncoders;
internal IEnumerable<KeyValuePair<IImageFormat, ImageEncoder>> ImageEncoders => this.mimeTypeEncoders;
/// <summary>
/// Registers a new format provider.
@ -117,7 +117,7 @@ public class ImageFormatManager
/// </summary>
/// <param name="imageFormat">The image format to register the encoder for.</param>
/// <param name="encoder">The encoder to use,</param>
public void SetEncoder(IImageFormat imageFormat, IImageEncoder encoder)
public void SetEncoder(IImageFormat imageFormat, ImageEncoder encoder)
{
Guard.NotNull(imageFormat, nameof(imageFormat));
Guard.NotNull(encoder, nameof(encoder));
@ -172,12 +172,12 @@ public class ImageFormatManager
/// For the specified mime type find the encoder.
/// </summary>
/// <param name="format">The format to discover</param>
/// <returns>The <see cref="IImageEncoder"/> if found otherwise null</returns>
public IImageEncoder FindEncoder(IImageFormat format)
/// <returns>The <see cref="ImageEncoder"/> if found otherwise null</returns>
public ImageEncoder FindEncoder(IImageFormat format)
{
Guard.NotNull(format, nameof(format));
return this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder)
return this.mimeTypeEncoders.TryGetValue(format, out ImageEncoder encoder)
? encoder
: null;
}

8
src/ImageSharp/Image.cs

@ -96,7 +96,7 @@ public abstract partial class Image : IImage, IConfigurationProvider
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The encoder to save the image with.</param>
/// <exception cref="ArgumentNullException">Thrown if the stream or encoder is null.</exception>
public void Save(Stream stream, IImageEncoder encoder)
public void Save(Stream stream, ImageEncoder encoder)
{
Guard.NotNull(stream, nameof(stream));
Guard.NotNull(encoder, nameof(encoder));
@ -113,7 +113,7 @@ public abstract partial class Image : IImage, IConfigurationProvider
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <exception cref="ArgumentNullException">Thrown if the stream or encoder is null.</exception>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public Task SaveAsync(Stream stream, IImageEncoder encoder, CancellationToken cancellationToken = default)
public Task SaveAsync(Stream stream, ImageEncoder encoder, CancellationToken cancellationToken = default)
{
Guard.NotNull(stream, nameof(stream));
Guard.NotNull(encoder, nameof(encoder));
@ -184,11 +184,11 @@ public abstract partial class Image : IImage, IConfigurationProvider
private class EncodeVisitor : IImageVisitor, IImageVisitorAsync
{
private readonly IImageEncoder encoder;
private readonly ImageEncoder encoder;
private readonly Stream stream;
public EncodeVisitor(IImageEncoder encoder, Stream stream)
public EncodeVisitor(ImageEncoder encoder, Stream stream)
{
this.encoder = encoder;
this.stream = stream;

18
src/ImageSharp/ImageExtensions.cs

@ -43,7 +43,7 @@ public static partial class ImageExtensions
/// <param name="encoder">The encoder to save the image with.</param>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="ArgumentNullException">The encoder is null.</exception>
public static void Save(this Image source, string path, IImageEncoder encoder)
public static void Save(this Image source, string path, ImageEncoder encoder)
{
Guard.NotNull(path, nameof(path));
Guard.NotNull(encoder, nameof(encoder));
@ -66,16 +66,14 @@ public static partial class ImageExtensions
public static async Task SaveAsync(
this Image source,
string path,
IImageEncoder encoder,
ImageEncoder encoder,
CancellationToken cancellationToken = default)
{
Guard.NotNull(path, nameof(path));
Guard.NotNull(encoder, nameof(encoder));
using (Stream fs = source.GetConfiguration().FileSystem.Create(path))
{
await source.SaveAsync(fs, encoder, cancellationToken).ConfigureAwait(false);
}
using Stream fs = source.GetConfiguration().FileSystem.Create(path);
await source.SaveAsync(fs, encoder, cancellationToken).ConfigureAwait(false);
}
/// <summary>
@ -98,14 +96,14 @@ public static partial class ImageExtensions
throw new NotSupportedException("Cannot write to the stream.");
}
IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
ImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
if (encoder is null)
{
StringBuilder sb = new();
sb.AppendLine("No encoder was found for the provided mime type. Registered encoders include:");
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
foreach (KeyValuePair<IImageFormat, ImageEncoder> val in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
{
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}
@ -142,14 +140,14 @@ public static partial class ImageExtensions
throw new NotSupportedException("Cannot write to the stream.");
}
IImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
ImageEncoder encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
if (encoder is null)
{
StringBuilder sb = new();
sb.AppendLine("No encoder was found for the provided mime type. Registered encoders include:");
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
foreach (KeyValuePair<IImageFormat, ImageEncoder> val in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
{
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}

10
tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs

@ -56,7 +56,7 @@ public class ImageFormatManagerTests
[Fact]
public void RegisterNullMimeTypeEncoder()
{
Assert.Throws<ArgumentNullException>(() => this.DefaultFormatsManager.SetEncoder(null, new Mock<IImageEncoder>().Object));
Assert.Throws<ArgumentNullException>(() => this.DefaultFormatsManager.SetEncoder(null, new Mock<ImageEncoder>().Object));
Assert.Throws<ArgumentNullException>(() => this.DefaultFormatsManager.SetEncoder(BmpFormat.Instance, null));
Assert.Throws<ArgumentNullException>(() => this.DefaultFormatsManager.SetEncoder(null, null));
}
@ -72,14 +72,14 @@ public class ImageFormatManagerTests
[Fact]
public void RegisterMimeTypeEncoderReplacesLast()
{
IImageEncoder encoder1 = new Mock<IImageEncoder>().Object;
ImageEncoder encoder1 = new Mock<ImageEncoder>().Object;
this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder1);
IImageEncoder found = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat);
ImageEncoder found = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat);
Assert.Equal(encoder1, found);
IImageEncoder encoder2 = new Mock<IImageEncoder>().Object;
ImageEncoder encoder2 = new Mock<ImageEncoder>().Object;
this.FormatsManagerEmpty.SetEncoder(TestFormat.GlobalTestFormat, encoder2);
IImageEncoder found2 = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat);
ImageEncoder found2 = this.FormatsManagerEmpty.FindEncoder(TestFormat.GlobalTestFormat);
Assert.Equal(encoder2, found2);
Assert.NotEqual(found, found2);
}

8
tests/ImageSharp.Tests/Image/ImageSaveTests.cs

@ -16,8 +16,8 @@ public class ImageSaveTests : IDisposable
{
private readonly Image<Rgba32> image;
private readonly Mock<IFileSystem> fileSystem;
private readonly Mock<IImageEncoder> encoder;
private readonly Mock<IImageEncoder> encoderNotInFormat;
private readonly Mock<ImageEncoder> encoder;
private readonly Mock<ImageEncoder> encoderNotInFormat;
private IImageFormatDetector localMimeTypeDetector;
private Mock<IImageFormat> localImageFormat;
@ -27,9 +27,9 @@ public class ImageSaveTests : IDisposable
this.localImageFormat.Setup(x => x.FileExtensions).Returns(new[] { "png" });
this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormat.Object);
this.encoder = new Mock<IImageEncoder>();
this.encoder = new Mock<ImageEncoder>();
this.encoderNotInFormat = new Mock<IImageEncoder>();
this.encoderNotInFormat = new Mock<ImageEncoder>();
this.fileSystem = new Mock<IFileSystem>();
var config = new Configuration

2
tests/ImageSharp.Tests/Image/ImageTests.Save.cs

@ -68,7 +68,7 @@ public partial class ImageTests
{
using var image = new Image<Rgba32>(5, 5);
image.Dispose();
IImageEncoder encoder = Mock.Of<IImageEncoder>();
ImageEncoder encoder = Mock.Of<ImageEncoder>();
using (var stream = new MemoryStream())
{
Assert.Throws<ObjectDisposedException>(() => image.Save(stream, encoder));

4
tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs

@ -102,7 +102,7 @@ public partial class ImageTests
{
var image = new Image<Rgba32>(5, 5);
image.Dispose();
IImageEncoder encoder = Mock.Of<IImageEncoder>();
ImageEncoder encoder = Mock.Of<ImageEncoder>();
using (var stream = new MemoryStream())
{
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await image.SaveAsync(stream, encoder));
@ -120,7 +120,7 @@ public partial class ImageTests
{
using (var image = new Image<Rgba32>(5, 5))
{
IImageEncoder encoder = image.DetectEncoder(filename);
ImageEncoder encoder = image.DetectEncoder(filename);
using (var stream = new MemoryStream())
{
var asyncStream = new AsyncStreamWrapper(stream, () => false);

2
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -328,7 +328,7 @@ public partial class ImageTests
public void KnownExtension_ReturnsEncoder()
{
using var image = new Image<L8>(1, 1);
IImageEncoder encoder = image.DetectEncoder("dummy.png");
ImageEncoder encoder = image.DetectEncoder("dummy.png");
Assert.NotNull(encoder);
Assert.IsType<PngEncoder>(encoder);
}

2
tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs

@ -55,7 +55,7 @@ public class LargeImageIntegrationTests
Configuration configuration = Configuration.Default.Clone();
configuration.PreferContiguousImageBuffers = true;
IImageEncoder encoder = configuration.ImageFormatsManager.FindEncoder(
ImageEncoder encoder = configuration.ImageFormatsManager.FindEncoder(
configuration.ImageFormatsManager.FindFormatByFileExtension(formatInner));
string dir = TestEnvironment.CreateOutputDirectory(".Temp");
string path = Path.Combine(dir, $"{Guid.NewGuid()}.{formatInner}");

2
tests/ImageSharp.Tests/Metadata/Profiles/XMP/XmpProfileTests.cs

@ -242,7 +242,7 @@ public class XmpProfileTests
return profile;
}
private static Image<Rgba32> WriteAndRead(Image<Rgba32> image, IImageEncoder encoder)
private static Image<Rgba32> WriteAndRead(Image<Rgba32> image, ImageEncoder encoder)
{
using (var memStream = new MemoryStream())
{

9
tests/ImageSharp.Tests/TestFormat.cs

@ -233,7 +233,7 @@ public class TestFormat : IConfigurationModule, IImageFormat
public DecoderOptions GeneralOptions { get; set; } = new();
}
public class TestEncoder : IImageEncoder
public class TestEncoder : ImageEncoder
{
private readonly TestFormat testFormat;
@ -243,14 +243,13 @@ public class TestFormat : IConfigurationModule, IImageFormat
public IEnumerable<string> FileExtensions => this.testFormat.SupportedExtensions;
public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
public override void Encode<TPixel>(Image<TPixel> image, Stream stream)
{
// TODO record this happened so we can verify it.
}
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> => Task.CompletedTask; // TODO record this happened so we can verify it.
public override Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
=> Task.CompletedTask; // TODO record this happened so we can verify it.
}
public struct TestPixelForAgnosticDecode : IPixel<TestPixelForAgnosticDecode>

4
tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs

@ -158,7 +158,7 @@ public class ImagingTestCaseUtility
public string SaveTestOutputFile(
Image image,
string extension = null,
IImageEncoder encoder = null,
ImageEncoder encoder = null,
object testOutputDetails = null,
bool appendPixelTypeToFileName = true,
bool appendSourceFileOrDescription = true)
@ -203,7 +203,7 @@ public class ImagingTestCaseUtility
public string[] SaveTestOutputFileMultiFrame<TPixel>(
Image<TPixel> image,
string extension = "png",
IImageEncoder encoder = null,
ImageEncoder encoder = null,
object testOutputDetails = null,
bool appendPixelTypeToFileName = true)
where TPixel : unmanaged, IPixel<TPixel>

21
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs

@ -3,34 +3,27 @@
using System.Drawing.Imaging;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
public class SystemDrawingReferenceEncoder : IImageEncoder
public class SystemDrawingReferenceEncoder : ImageEncoder
{
private readonly System.Drawing.Imaging.ImageFormat imageFormat;
private readonly ImageFormat imageFormat;
public SystemDrawingReferenceEncoder(ImageFormat imageFormat)
{
this.imageFormat = imageFormat;
}
=> this.imageFormat = imageFormat;
public static SystemDrawingReferenceEncoder Png { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Png);
public static SystemDrawingReferenceEncoder Bmp { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Bmp);
public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
public override void Encode<TPixel>(Image<TPixel> image, Stream stream)
{
using (System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image))
{
sdBitmap.Save(stream, this.imageFormat);
}
using System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image);
sdBitmap.Save(stream, this.imageFormat);
}
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
public override Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
using (System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image))
{

8
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs

@ -26,7 +26,7 @@ public static partial class TestEnvironment
return Configuration.ImageFormatsManager.FindDecoder(format);
}
internal static IImageEncoder GetReferenceEncoder(string filePath)
internal static ImageEncoder GetReferenceEncoder(string filePath)
{
IImageFormat format = GetImageFormat(filePath);
return Configuration.ImageFormatsManager.FindEncoder(format);
@ -43,7 +43,7 @@ public static partial class TestEnvironment
this Configuration cfg,
IImageFormat imageFormat,
ImageDecoder decoder,
IImageEncoder encoder,
ImageEncoder encoder,
IImageFormatDetector detector)
{
cfg.ImageFormatsManager.SetDecoder(imageFormat, decoder);
@ -61,8 +61,8 @@ public static partial class TestEnvironment
new WebpConfigurationModule(),
new TiffConfigurationModule());
IImageEncoder pngEncoder = IsWindows ? SystemDrawingReferenceEncoder.Png : new ImageSharpPngEncoderWithDefaultConfiguration();
IImageEncoder bmpEncoder = IsWindows ? SystemDrawingReferenceEncoder.Bmp : new BmpEncoder();
ImageEncoder pngEncoder = IsWindows ? SystemDrawingReferenceEncoder.Png : new ImageSharpPngEncoderWithDefaultConfiguration();
ImageEncoder bmpEncoder = IsWindows ? SystemDrawingReferenceEncoder.Bmp : new BmpEncoder();
// Magick codecs should work on all platforms
cfg.ConfigureCodecs(

11
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -19,6 +19,7 @@ public static class TestImageExtensions
/// <summary>
/// TODO: Consider adding this private processor to the library
/// </summary>
/// <param name="ctx">The image processing context.</param>
public static void MakeOpaque(this IImageProcessingContext ctx) =>
ctx.ApplyProcessor(new MakeOpaqueProcessor());
@ -29,7 +30,7 @@ public static class TestImageExtensions
string extension = "png",
bool appendPixelTypeToFileName = true,
bool appendSourceFileOrDescription = true,
IImageEncoder encoder = null)
ImageEncoder encoder = null)
=> image.DebugSave(
provider,
(object)testOutputDetails,
@ -56,7 +57,7 @@ public static class TestImageExtensions
string extension = "png",
bool appendPixelTypeToFileName = true,
bool appendSourceFileOrDescription = true,
IImageEncoder encoder = null)
ImageEncoder encoder = null)
{
if (TestEnvironment.RunsWithCodeCoverage)
{
@ -76,7 +77,7 @@ public static class TestImageExtensions
public static void DebugSave(
this Image image,
ITestImageProvider provider,
IImageEncoder encoder,
ImageEncoder encoder,
FormattableString testOutputDetails,
bool appendPixelTypeToFileName = true)
=> image.DebugSave(provider, encoder, (object)testOutputDetails, appendPixelTypeToFileName);
@ -92,7 +93,7 @@ public static class TestImageExtensions
public static void DebugSave(
this Image image,
ITestImageProvider provider,
IImageEncoder encoder,
ImageEncoder encoder,
object testOutputDetails = null,
bool appendPixelTypeToFileName = true)
=> provider.Utility.SaveTestOutputFile(
@ -663,7 +664,7 @@ public static class TestImageExtensions
ITestImageProvider provider,
string extension,
object testOutputDetails,
IImageEncoder encoder,
ImageEncoder encoder,
ImageComparer customComparer = null,
bool appendPixelTypeToFileName = true,
string referenceImageExtension = null,

4
tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs

@ -62,7 +62,7 @@ public class TestEnvironmentTests
return;
}
IImageEncoder encoder = TestEnvironment.GetReferenceEncoder(fileName);
ImageEncoder encoder = TestEnvironment.GetReferenceEncoder(fileName);
Assert.IsType(expectedEncoderType, encoder);
}
@ -96,7 +96,7 @@ public class TestEnvironmentTests
return;
}
IImageEncoder encoder = TestEnvironment.GetReferenceEncoder(fileName);
ImageEncoder encoder = TestEnvironment.GetReferenceEncoder(fileName);
Assert.IsType(expectedEncoderType, encoder);
}

Loading…
Cancel
Save