|  | @@ -19,8 +19,8 @@ namespace Jellyfin.Drawing.Skia;
 | 
	
		
			
				|  |  |  /// </summary>
 | 
	
		
			
				|  |  |  public class SkiaEncoder : IImageEncoder
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +    private const string SvgFormat = "svg";
 | 
	
		
			
				|  |  |      private static readonly HashSet<string> _transparentImageTypes = new(StringComparer.OrdinalIgnoreCase) { ".png", ".gif", ".webp" };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      private readonly ILogger<SkiaEncoder> _logger;
 | 
	
		
			
				|  |  |      private readonly IApplicationPaths _appPaths;
 | 
	
		
			
				|  |  |      private static readonly SKImageFilter _imageFilter;
 | 
	
	
		
			
				|  | @@ -89,12 +89,13 @@ public class SkiaEncoder : IImageEncoder
 | 
	
		
			
				|  |  |              // working on windows at least
 | 
	
		
			
				|  |  |              "cr2",
 | 
	
		
			
				|  |  |              "nef",
 | 
	
		
			
				|  |  | -            "arw"
 | 
	
		
			
				|  |  | +            "arw",
 | 
	
		
			
				|  |  | +            SvgFormat
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// <inheritdoc/>
 | 
	
		
			
				|  |  |      public IReadOnlyCollection<ImageFormat> SupportedOutputFormats
 | 
	
		
			
				|  |  | -        => new HashSet<ImageFormat> { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
 | 
	
		
			
				|  |  | +        => new HashSet<ImageFormat> { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png, ImageFormat.Svg };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// <summary>
 | 
	
		
			
				|  |  |      /// Check if the native lib is available.
 | 
	
	
		
			
				|  | @@ -312,6 +313,31 @@ public class SkiaEncoder : IImageEncoder
 | 
	
		
			
				|  |  |          return Decode(path, false, orientation, out _);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private SKBitmap? GetBitmapFromSvg(string path)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        if (!File.Exists(path))
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            throw new FileNotFoundException("File not found", path);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        using var svg = SKSvg.CreateFromFile(path);
 | 
	
		
			
				|  |  | +        if (svg.Drawable is null)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        var width = (int)Math.Round(svg.Drawable.Bounds.Width);
 | 
	
		
			
				|  |  | +        var height = (int)Math.Round(svg.Drawable.Bounds.Height);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        var bitmap = new SKBitmap(width, height);
 | 
	
		
			
				|  |  | +        using var canvas = new SKCanvas(bitmap);
 | 
	
		
			
				|  |  | +        canvas.DrawPicture(svg.Picture);
 | 
	
		
			
				|  |  | +        canvas.Flush();
 | 
	
		
			
				|  |  | +        canvas.Save();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return bitmap;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private SKBitmap OrientImage(SKBitmap bitmap, SKEncodedOrigin origin)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          var needsFlip = origin is SKEncodedOrigin.LeftBottom or SKEncodedOrigin.LeftTop or SKEncodedOrigin.RightBottom or SKEncodedOrigin.RightTop;
 | 
	
	
		
			
				|  | @@ -402,6 +428,12 @@ public class SkiaEncoder : IImageEncoder
 | 
	
		
			
				|  |  |              return inputPath;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        if (outputFormat == ImageFormat.Svg
 | 
	
		
			
				|  |  | +            && !inputFormat.Equals(SvgFormat, StringComparison.OrdinalIgnoreCase))
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            throw new ArgumentException($"Requested svg output from {inputFormat} input");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          var skiaOutputFormat = GetImageFormat(outputFormat);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          var hasBackgroundColor = !string.IsNullOrWhiteSpace(options.BackgroundColor);
 | 
	
	
		
			
				|  | @@ -409,7 +441,10 @@ public class SkiaEncoder : IImageEncoder
 | 
	
		
			
				|  |  |          var blur = options.Blur ?? 0;
 | 
	
		
			
				|  |  |          var hasIndicator = options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        using var bitmap = GetBitmap(inputPath, autoOrient, orientation);
 | 
	
		
			
				|  |  | +        using var bitmap = inputFormat.Equals(SvgFormat, StringComparison.OrdinalIgnoreCase)
 | 
	
		
			
				|  |  | +            ? GetBitmapFromSvg(inputPath)
 | 
	
		
			
				|  |  | +            : GetBitmap(inputPath, autoOrient, orientation);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if (bitmap is null)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              throw new InvalidDataException($"Skia unable to read image {inputPath}");
 |