|  | @@ -13,6 +13,9 @@ using static Jellyfin.Drawing.Skia.SkiaHelper;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +    /// <summary>
 | 
	
		
			
				|  |  | +    /// Image encoder that uses <see cref="SkiaSharp"/> to manipulate images.
 | 
	
		
			
				|  |  | +    /// </summary>
 | 
	
		
			
				|  |  |      public class SkiaEncoder : IImageEncoder
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          private readonly ILogger _logger;
 | 
	
	
		
			
				|  | @@ -22,6 +25,9 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |          private static readonly HashSet<string> _transparentImageTypes
 | 
	
		
			
				|  |  |              = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".png", ".gif", ".webp" };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <summary>
 | 
	
		
			
				|  |  | +        /// Initializes a new instance of the <see cref="SkiaEncoder"/> class.
 | 
	
		
			
				|  |  | +        /// </summary>
 | 
	
		
			
				|  |  |          public SkiaEncoder(
 | 
	
		
			
				|  |  |              ILogger<SkiaEncoder> logger,
 | 
	
		
			
				|  |  |              IApplicationPaths appPaths,
 | 
	
	
		
			
				|  | @@ -32,12 +38,16 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |              _localizationManager = localizationManager;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public string Name => "Skia";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public bool SupportsImageCollageCreation => true;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public bool SupportsImageEncoding => true;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public IReadOnlyCollection<string> SupportedInputFormats =>
 | 
	
		
			
				|  |  |              new HashSet<string>(StringComparer.OrdinalIgnoreCase)
 | 
	
		
			
				|  |  |              {
 | 
	
	
		
			
				|  | @@ -65,6 +75,7 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |                  "arw"
 | 
	
		
			
				|  |  |              };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public IReadOnlyCollection<ImageFormat> SupportedOutputFormats
 | 
	
		
			
				|  |  |              => new HashSet<ImageFormat>() { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -80,6 +91,11 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |          private static bool IsTransparent(SKColor color)
 | 
	
		
			
				|  |  |              => (color.Red == 255 && color.Green == 255 && color.Blue == 255) || color.Alpha == 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <summary>
 | 
	
		
			
				|  |  | +        /// Convert a <see cref="ImageFormat"/> to a <see cref="SKEncodedImageFormat"/>.
 | 
	
		
			
				|  |  | +        /// </summary>
 | 
	
		
			
				|  |  | +        /// <param name="selectedFormat">The format to convert.</param>
 | 
	
		
			
				|  |  | +        /// <returns>The converted format.</returns>
 | 
	
		
			
				|  |  |          public static SKEncodedImageFormat GetImageFormat(ImageFormat selectedFormat)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              switch (selectedFormat)
 | 
	
	
		
			
				|  | @@ -186,6 +202,9 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <inheritdoc />
 | 
	
		
			
				|  |  | +        /// <exception cref="ArgumentNullException">If path is null.</exception>
 | 
	
		
			
				|  |  | +        /// <exception cref="FileNotFoundException">If the path is not valid.</exception>
 | 
	
		
			
				|  |  | +        /// <exception cref="SkiaCodecException">If the file at the specified path could not be used to generate a codec.</exception>
 | 
	
		
			
				|  |  |          public ImageDimensions GetImageSize(string path)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              if (path == null)
 | 
	
	
		
			
				|  | @@ -497,6 +516,7 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              if (string.IsNullOrWhiteSpace(inputPath))
 | 
	
	
		
			
				|  | @@ -612,6 +632,7 @@ namespace Jellyfin.Drawing.Skia
 | 
	
		
			
				|  |  |              return outputPath;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        /// <inheritdoc/>
 | 
	
		
			
				|  |  |          public void CreateImageCollage(ImageCollageOptions options)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              double ratio = (double)options.Width / options.Height;
 |