33
44using System ;
55using System . IO ;
6+ using System . Runtime . CompilerServices ;
7+ using SixLabors . ImageSharp . Advanced ;
68using SixLabors . ImageSharp . Formats ;
79using SixLabors . ImageSharp . PixelFormats ;
810
@@ -11,10 +13,12 @@ namespace SixLabors.ImageSharp.Web
1113 /// <summary>
1214 /// A class encapsulating an image with a particular file encoding.
1315 /// </summary>
14- /// <seealso cref="IDisposable" />
16+ /// <seealso cref="IDisposable"/>
1517 public sealed class FormattedImage : IDisposable
1618 {
19+ private readonly ImageFormatManager imageFormatsManager ;
1720 private IImageFormat format ;
21+ private IImageEncoder encoder ;
1822
1923 /// <summary>
2024 /// Initializes a new instance of the <see cref="FormattedImage"/> class.
@@ -23,8 +27,9 @@ public sealed class FormattedImage : IDisposable
2327 /// <param name="format">The format.</param>
2428 internal FormattedImage ( Image < Rgba32 > image , IImageFormat format )
2529 {
26- this . format = format ;
2730 this . Image = image ;
31+ this . imageFormatsManager = image . GetConfiguration ( ) . ImageFormatsManager ;
32+ this . Format = format ;
2833 }
2934
3035 /// <summary>
@@ -38,7 +43,40 @@ internal FormattedImage(Image<Rgba32> image, IImageFormat format)
3843 public IImageFormat Format
3944 {
4045 get => this . format ;
41- set => this . format = value ?? throw new ArgumentNullException ( nameof ( value ) ) ;
46+ set
47+ {
48+ if ( value is null )
49+ {
50+ ThrowNull ( nameof ( value ) ) ;
51+ }
52+
53+ this . format = value ;
54+ this . encoder = this . imageFormatsManager . FindEncoder ( value ) ;
55+ }
56+ }
57+
58+ /// <summary>
59+ /// Gets or sets the encoder.
60+ /// </summary>
61+ public IImageEncoder Encoder
62+ {
63+ get => this . encoder ;
64+ set
65+ {
66+ if ( value is null )
67+ {
68+ ThrowNull ( nameof ( value ) ) ;
69+ }
70+
71+ // The given type should match the format encoder.
72+ IImageEncoder reference = this . imageFormatsManager . FindEncoder ( this . Format ) ;
73+ if ( reference . GetType ( ) != value . GetType ( ) )
74+ {
75+ ThrowInvalid ( nameof ( value ) ) ;
76+ }
77+
78+ this . encoder = value ;
79+ }
4280 }
4381
4482 /// <summary>
@@ -54,18 +92,25 @@ public static FormattedImage Load(Configuration configuration, Stream source)
5492 }
5593
5694 /// <summary>
57- /// Saves the specified destination.
95+ /// Saves image to the specified destination stream .
5896 /// </summary>
59- /// <param name="destination">The destination.</param>
60- public void Save ( Stream destination ) => this . Image . Save ( destination , this . format ) ;
97+ /// <param name="destination">The destination stream .</param>
98+ public void Save ( Stream destination ) => this . Image . Save ( destination , this . encoder ) ;
6199
62100 /// <summary>
63- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
101+ /// Performs application-defined tasks associated with freeing, releasing, or resetting
102+ /// unmanaged resources.
64103 /// </summary>
65104 public void Dispose ( )
66105 {
67106 this . Image ? . Dispose ( ) ;
68107 this . Image = null ;
69108 }
109+
110+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
111+ private static void ThrowNull ( string name ) => throw new ArgumentNullException ( name ) ;
112+
113+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
114+ private static void ThrowInvalid ( string name ) => throw new ArgumentException ( name ) ;
70115 }
71116}
0 commit comments