2021-10-27 21:47:58 +00:00
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Net.Http;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Avalonia.Controls;
|
|
|
|
using Avalonia.Media;
|
|
|
|
using Avalonia.Media.Imaging;
|
|
|
|
using SkiaSharp;
|
|
|
|
using Wabbajack.Hashing.xxHash64;
|
2021-11-08 13:32:51 +00:00
|
|
|
using Wabbajack.Paths;
|
2021-10-27 21:47:58 +00:00
|
|
|
using Wabbajack.Paths.IO;
|
|
|
|
using Wabbajack.RateLimiter;
|
2021-11-10 23:13:02 +00:00
|
|
|
using Wabbajack.Services.OSIntegrated;
|
2021-11-08 13:32:51 +00:00
|
|
|
using Wabbajack.VFS;
|
2021-10-27 21:47:58 +00:00
|
|
|
|
|
|
|
namespace Wabbajack.App.Models;
|
|
|
|
|
|
|
|
public class ImageCache
|
|
|
|
{
|
|
|
|
private readonly Configuration _configuration;
|
|
|
|
private readonly HttpClient _client;
|
|
|
|
private readonly IResource<HttpClient> _limiter;
|
2021-11-08 13:32:51 +00:00
|
|
|
private readonly FileHashCache _hashCache;
|
2021-10-27 21:47:58 +00:00
|
|
|
|
2021-11-08 13:32:51 +00:00
|
|
|
public ImageCache(Configuration configuration, HttpClient client, IResource<HttpClient> limiter, FileHashCache hashCache)
|
2021-10-27 21:47:58 +00:00
|
|
|
{
|
|
|
|
_configuration = configuration;
|
|
|
|
_configuration.ImageCacheLocation.CreateDirectory();
|
|
|
|
_client = client;
|
|
|
|
_limiter = limiter;
|
2021-11-08 13:32:51 +00:00
|
|
|
_hashCache = hashCache;
|
2021-10-27 21:47:58 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 23:03:49 +00:00
|
|
|
public async Task<IBitmap> From(Uri uri, int width, int height)
|
2021-10-27 21:47:58 +00:00
|
|
|
{
|
|
|
|
var hash = (await Encoding.UTF8.GetBytes(uri.ToString()).Hash()).ToHex();
|
2021-10-27 23:03:49 +00:00
|
|
|
var file = _configuration.ImageCacheLocation.Combine(hash + $"_{width}_{height}");
|
|
|
|
|
2021-10-27 21:47:58 +00:00
|
|
|
if (!file.FileExists())
|
|
|
|
{
|
|
|
|
using var job = await _limiter.Begin("Loading Image", 0, CancellationToken.None);
|
2021-10-27 23:03:49 +00:00
|
|
|
|
2021-10-27 21:47:58 +00:00
|
|
|
var wdata = await _client.GetByteArrayAsync(uri);
|
2021-10-27 23:03:49 +00:00
|
|
|
var resized = SKBitmap.Decode(wdata).Resize(new SKSizeI(width, height), SKFilterQuality.High);
|
|
|
|
await file.WriteAllBytesAsync(resized.Encode(SKEncodedImageFormat.Webp, 90).ToArray());
|
2021-10-27 21:47:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var data = await file.ReadAllBytesAsync();
|
|
|
|
return new Bitmap(new MemoryStream(data));
|
|
|
|
}
|
|
|
|
|
2021-11-08 13:32:51 +00:00
|
|
|
public async Task<IBitmap> From(AbsolutePath image, int width, int height)
|
|
|
|
{
|
|
|
|
var hash = await _hashCache.FileHashCachedAsync(image, CancellationToken.None);
|
|
|
|
var file = _configuration.ImageCacheLocation.Combine(hash + $"_{width}_{height}");
|
|
|
|
|
|
|
|
if (!file.FileExists())
|
|
|
|
{
|
|
|
|
var resized = SKBitmap.Decode(image.ToString()).Resize(new SKSizeI(width, height), SKFilterQuality.High);
|
|
|
|
await file.WriteAllBytesAsync(resized.Encode(SKEncodedImageFormat.Webp, 90).ToArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
var data = await file.ReadAllBytesAsync();
|
|
|
|
return new Bitmap(new MemoryStream(data));
|
|
|
|
}
|
2021-10-27 21:47:58 +00:00
|
|
|
}
|