92 lines
2.7 KiB
C#
92 lines
2.7 KiB
C#
using Harmonia.Core.Caching;
|
|
using Harmonia.Core.Imaging;
|
|
using Harmonia.Core.Models;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.UI.Xaml.Media.Imaging;
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Harmonia.WinUI.Caching;
|
|
|
|
public class AudioBitmapImageCache(IAudioImageExtractor audioImageExtractor) : MemoryCache<Song, BitmapImage>, IAudioBitmapImageCache
|
|
{
|
|
protected virtual int MaxImageWidthOrHeight => 1000;
|
|
|
|
protected override MemoryCacheOptions Options => new()
|
|
{
|
|
SizeLimit = 200_000_000,
|
|
CompactionPercentage = 0.2,
|
|
};
|
|
|
|
protected override TimeSpan SlidingExpiration => TimeSpan.FromSeconds(600);
|
|
|
|
protected override int MaxConcurrentRequests => 8;
|
|
|
|
protected override object? GetKey(Song key)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(key.ImageHash) == false)
|
|
{
|
|
return key.ImageHash;
|
|
}
|
|
else if (string.IsNullOrWhiteSpace(key.ImageName) == false)
|
|
{
|
|
return key.ImageName;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
protected override async ValueTask<BitmapImage?> FetchAsync(Song key, CancellationToken cancellationToken)
|
|
{
|
|
SongPictureInfo? songPictureInfo = await audioImageExtractor.ExtractImageAsync(key.FileName, cancellationToken);
|
|
|
|
if (songPictureInfo == null)
|
|
return null;
|
|
|
|
using MemoryStream stream = new(songPictureInfo.Data);
|
|
|
|
BitmapImage bitmapImage = new();
|
|
|
|
await bitmapImage.SetSourceAsync(stream.AsRandomAccessStream());
|
|
|
|
bitmapImage.DecodePixelWidth = GetDecodePixelWidth(bitmapImage);
|
|
bitmapImage.DecodePixelHeight = GetDecodePixelHeight(bitmapImage);
|
|
|
|
return bitmapImage;
|
|
}
|
|
|
|
private int GetDecodePixelWidth(BitmapImage bitmapImage)
|
|
{
|
|
int originalImageWidth = bitmapImage.PixelWidth;
|
|
int orignalImageHeight = bitmapImage.PixelHeight;
|
|
|
|
if (originalImageWidth <= MaxImageWidthOrHeight && orignalImageHeight <= MaxImageWidthOrHeight)
|
|
return 0;
|
|
|
|
if (orignalImageHeight > originalImageWidth)
|
|
return 0;
|
|
|
|
return MaxImageWidthOrHeight;
|
|
}
|
|
|
|
private int GetDecodePixelHeight(BitmapImage bitmapImage)
|
|
{
|
|
int originalImageWidth = bitmapImage.PixelWidth;
|
|
int orignalImageHeight = bitmapImage.PixelHeight;
|
|
|
|
if (originalImageWidth <= MaxImageWidthOrHeight && orignalImageHeight <= MaxImageWidthOrHeight)
|
|
return 0;
|
|
|
|
if (originalImageWidth > orignalImageHeight)
|
|
return 0;
|
|
|
|
return MaxImageWidthOrHeight;
|
|
}
|
|
|
|
protected override long GetEntrySize(BitmapImage entry)
|
|
{
|
|
return entry.DecodePixelWidth * entry.DecodePixelHeight;
|
|
}
|
|
} |