@ -1,18 +1,15 @@
@@ -1,18 +1,15 @@
using System.Diagnostics.CodeAnalysis ;
using System.Diagnostics.CodeAnalysis ;
using System.Globalization ;
using System.Security.Cryptography ;
using System.Text ;
using Blurhash.Image Sharp ;
using Blurhash.Skia Sharp ;
using ErsatzTV.Core ;
using ErsatzTV.Core.Domain ;
using ErsatzTV.Core.FFmpeg ;
using ErsatzTV.Core.Interfaces.FFmpeg ;
using ErsatzTV.Core.Interfaces.Images ;
using ErsatzTV.Core.Interfaces.Metadata ;
using SixLabors.ImageSharp ;
using SixLabors.ImageSharp.PixelFormats ;
using SixLabors.ImageSharp.Processing ;
using Image = SixLabors . ImageSharp . Image ;
using SkiaSharp ;
namespace ErsatzTV.Infrastructure.Images ;
@ -123,28 +120,42 @@ public class ImageCache : IImageCache
@@ -123,28 +120,42 @@ public class ImageCache : IImageCache
return Path . Combine ( baseFolder , fileName ) ;
}
public async Task < string > CalculateBlurHash ( string fileName , ArtworkKind artworkKind , int x , int y )
public Task < string > CalculateBlurHash ( string fileName , ArtworkKind artworkKind , int x , int y )
{
string targetFile = GetPathForImage ( fileName , artworkKind , Option < int > . None ) ;
// ReSharper disable once ConvertToUsingDeclaration
using ( var image = await Image . LoadAsync < Rgba32 > ( targetFile ) )
using ( var image = SKBitmap . Decode ( targetFile ) )
{
// resize before calculating blur hash; it doesn't need giant images
if ( image . Height > 2 0 0 )
if ( image . Height > 2 0 0 | | image . Width > 2 0 0 )
{
image . Mutate ( i = > i . Resize ( 0 , 2 0 0 ) ) ;
}
else if ( image . Width > 2 0 0 )
{
image . Mutate ( i = > i . Resize ( 2 0 0 , 0 ) ) ;
int width , height ;
if ( image . Width > image . Height )
{
width = 2 0 0 ;
height = ( int ) Math . Round ( image . Height * ( 2 0 0.0 / image . Width ) ) ;
}
else
{
height = 2 0 0 ;
width = ( int ) Math . Round ( image . Width * ( 2 0 0.0 / image . Height ) ) ;
}
var info = new SKImageInfo ( width , height ) ;
// ReSharper disable once ConvertToUsingDeclaration
using ( SKBitmap resized = image . Resize ( info , SKSamplingOptions . Default ) )
{
return Task . FromResult ( Blurhasher . Encode ( resized , x , y ) ) ;
}
}
return Blurhasher . Encode ( image , x , y ) ;
return Task . FromResult ( Blurhasher . Encode ( image , x , y ) ) ;
}
}
public async Task < string > WriteBlurHash ( string blurHash , IDisplaySize targetSize )
public Task < string > WriteBlurHash ( string blurHash , IDisplaySize targetSize )
{
byte [ ] bytes = Encoding . UTF8 . GetBytes ( blurHash ) ;
string base64 = Convert . ToBase64String ( bytes ) . Replace ( "+" , "_" ) . Replace ( "/" , "-" ) . Replace ( "=" , "" ) ;
@ -155,17 +166,19 @@ public class ImageCache : IImageCache
@@ -155,17 +166,19 @@ public class ImageCache : IImageCache
_l ocalFileSystem . EnsureFolderExists ( folder ) ;
// ReSharper disable once ConvertToUsingDeclaration
// ReSharper disable once UseAwaitUsing
using ( FileStream fs = File . OpenWrite ( targetFile ) )
{
using ( Image < Rgb24 > image = Blurhasher . Decode ( blurHash , targetSize . Width , targetSize . Height ) )
using ( SKBitmap image = Blurhasher . Decode ( blurHash , targetSize . Width , targetSize . Height ) )
{
await image . SaveAsPngAsync ( fs ) ;
using ( SKData data = image . Encode ( SKEncodedImageFormat . Png , 1 0 0 ) )
{
data . SaveTo ( fs ) ;
}
}
}
}
return targetFile ;
return Task . FromResult ( targetFile ) ;
}
[SuppressMessage("Security", "CA5351:Do Not Use Broken Cryptographic Algorithms")]
@ -180,4 +193,4 @@ public class ImageCache : IImageCache
@@ -180,4 +193,4 @@ public class ImageCache : IImageCache
return await md5 . ComputeHashAsync ( fs ) ;
}
}
}
}