diff --git a/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs b/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
index 11dfd6c4..e3454fc1 100644
--- a/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
+++ b/back/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs
@@ -29,7 +29,7 @@ namespace Kyoo.Abstractions.Models
public interface IThumbnails
{
///
- /// A poster is a 9/16 format image with the cover of the resource.
+ /// A poster is a 2/3 format image with the cover of the resource.
///
public Image? Poster { get; set; }
@@ -82,6 +82,12 @@ namespace Kyoo.Abstractions.Models
return base.ConvertFrom(context, culture, value)!;
return new Image(source);
}
+
+ ///
+ public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
+ {
+ return false;
+ }
}
}
diff --git a/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs
index 6d33283e..8e421c7c 100644
--- a/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs
+++ b/back/src/Kyoo.Core/Controllers/Repositories/LocalRepository.cs
@@ -341,8 +341,15 @@ namespace Kyoo.Core.Controllers
if (obj == null)
throw new ArgumentNullException(nameof(obj));
await Validate(obj);
- // if (obj is IThumbnails thumbs)
- // await _thumbnailsManager.DownloadImages(thumbs);
+ if (obj is IThumbnails thumbs)
+ {
+ if (thumbs.Poster != null)
+ Database.Entry(thumbs).Reference(x => x.Poster).TargetEntry.State = EntityState.Added;
+ if (thumbs.Thumbnail != null)
+ Database.Entry(thumbs).Reference(x => x.Thumbnail).TargetEntry.State = EntityState.Added;
+ if (thumbs.Logo != null)
+ Database.Entry(thumbs).Reference(x => x.Logo).TargetEntry.State = EntityState.Added;
+ }
return obj;
}
@@ -427,6 +434,13 @@ namespace Kyoo.Core.Controllers
/// A representing the asynchronous operation.
protected virtual Task EditRelations(T resource, T changed, bool resetOld)
{
+ if (resource is IThumbnails thumbs)
+ {
+ // FIXME: I think this throws if poster is set to null.
+ Database.Entry(thumbs).Reference(x => x.Poster).TargetEntry.State = EntityState.Modified;
+ Database.Entry(thumbs).Reference(x => x.Thumbnail).TargetEntry.State = EntityState.Modified;
+ Database.Entry(thumbs).Reference(x => x.Logo).TargetEntry.State = EntityState.Modified;
+ }
return Validate(resource);
}
diff --git a/back/src/Kyoo.Core/Controllers/Repositories/UserRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/UserRepository.cs
index 89c00fdd..bf6f3e5e 100644
--- a/back/src/Kyoo.Core/Controllers/Repositories/UserRepository.cs
+++ b/back/src/Kyoo.Core/Controllers/Repositories/UserRepository.cs
@@ -66,6 +66,8 @@ namespace Kyoo.Core.Controllers
{
await base.Create(obj);
_database.Entry(obj).State = EntityState.Added;
+ if (obj.Logo != null)
+ _database.Entry(obj).Reference(x => x.Logo).TargetEntry.State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj;
diff --git a/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs b/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs
index b566c195..d11fd898 100644
--- a/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs
+++ b/back/src/Kyoo.Core/Controllers/ThumbnailsManager.cs
@@ -20,7 +20,7 @@ using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
-using BlurHashSharp.SkiaSharp;
+using Blurhash.SkiaSharp;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
using Microsoft.Extensions.Logging;
@@ -62,28 +62,33 @@ namespace Kyoo.Core.Controllers
await reader.CopyToAsync(file);
}
- private async Task _DownloadImage(string? url, string localPath, string what)
+ private async Task _DownloadImage(Image? image, string localPath, string what)
{
- if (url == null)
+ if (image == null)
return;
try
{
_logger.LogInformation("Downloading image {What}", what);
HttpClient client = _clientFactory.CreateClient();
- HttpResponseMessage response = await client.GetAsync(url);
+ HttpResponseMessage response = await client.GetAsync(image.Source);
response.EnsureSuccessStatusCode();
await using Stream reader = await response.Content.ReadAsStreamAsync();
- SKBitmap bitmap = SKBitmap.Decode(reader);
+ using SKCodec codec = SKCodec.Create(reader);
+ SKImageInfo info = codec.Info;
+ info.ColorType = SKColorType.Rgba8888;
+ SKBitmap bitmap = SKBitmap.Decode(codec, info);
bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.High);
await _WriteTo(bitmap, $"{localPath}.{ImageQuality.High.ToString().ToLowerInvariant()}.jpg");
- bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.Medium);
+ bitmap.Resize(new SKSizeI((int)(bitmap.Width / 1.5), (int)(bitmap.Height / 1.5)), SKFilterQuality.Medium);
await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Medium.ToString().ToLowerInvariant()}.jpg");
- bitmap.Resize(new SKSizeI(bitmap.Width, bitmap.Height), SKFilterQuality.Low);
+ bitmap.Resize(new SKSizeI(bitmap.Width / 2, bitmap.Height / 2), SKFilterQuality.Low);
await _WriteTo(bitmap, $"{localPath}.{ImageQuality.Low.ToString().ToLowerInvariant()}.jpg");
+
+ image.Blurhash = Blurhasher.Encode(bitmap, 4, 3);
}
catch (Exception ex)
{
@@ -99,9 +104,9 @@ namespace Kyoo.Core.Controllers
throw new ArgumentNullException(nameof(item));
string name = item is IResource res ? res.Slug : "???";
- await _DownloadImage(item.Poster?.Source, _GetBaseImagePath(item, "poster"), $"The poster of {name}");
- await _DownloadImage(item.Thumbnail?.Source, _GetBaseImagePath(item, "thumbnail"), $"The poster of {name}");
- await _DownloadImage(item.Logo?.Source, _GetBaseImagePath(item, "logo"), $"The poster of {name}");
+ await _DownloadImage(item.Poster, _GetBaseImagePath(item, "poster"), $"The poster of {name}");
+ await _DownloadImage(item.Thumbnail, _GetBaseImagePath(item, "thumbnail"), $"The poster of {name}");
+ await _DownloadImage(item.Logo, _GetBaseImagePath(item, "logo"), $"The poster of {name}");
}
private static string _GetBaseImagePath(T item, string image)
diff --git a/back/src/Kyoo.Core/Kyoo.Core.csproj b/back/src/Kyoo.Core/Kyoo.Core.csproj
index 332e4b6a..b4061a1c 100644
--- a/back/src/Kyoo.Core/Kyoo.Core.csproj
+++ b/back/src/Kyoo.Core/Kyoo.Core.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs b/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs
index 9e6c95f5..d02cb624 100644
--- a/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs
+++ b/back/src/Kyoo.Core/Views/Helper/CrudThumbsApi.cs
@@ -135,10 +135,8 @@ namespace Kyoo.Core.Api
///
public override async Task> Create([FromBody] T resource)
{
- // TODO: Remove this method and use a websocket API to do that.
- ActionResult ret = await base.Create(resource);
- await _thumbs.DownloadImages(ret.Value);
- return ret;
+ await _thumbs.DownloadImages(resource);
+ return await base.Create(resource);
}
}
}
diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/ImageConvertor.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/ImageConvertor.cs
deleted file mode 100644
index 52674995..00000000
--- a/back/src/Kyoo.Core/Views/Helper/Serializers/ImageConvertor.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Kyoo - A portable and vast media library solution.
-// Copyright (c) Kyoo.
-//
-// See AUTHORS.md and LICENSE file in the project root for full license information.
-//
-// Kyoo is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// any later version.
-//
-// Kyoo is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Kyoo. If not, see .
-
-using System;
-using System.Collections.Generic;
-using Kyoo.Abstractions.Models;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-namespace Kyoo.Core.Api
-{
- public class ImageConverter : JsonConverter
- {
- ///
- public override void WriteJson(JsonWriter writer, Image value, JsonSerializer serializer)
- {
- JObject obj = JObject.FromObject(value, serializer);
- obj.WriteTo(writer);
- }
-
- ///
- public override Image ReadJson(JsonReader reader,
- Type objectType,
- Image existingValue,
- bool hasExistingValue,
- JsonSerializer serializer)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
index 98429630..e8cacb82 100644
--- a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
+++ b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
@@ -78,29 +78,28 @@ namespace Kyoo.Core.Api
protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList properties = base.CreateProperties(type, memberSerialization);
- if (!type.IsAssignableTo(typeof(Image)))
- return properties;
+ // if (!type.IsAssignableTo(typeof(Image)))
+ // return properties;
// foreach ((int id, string image) in Images.ImageName)
// {
- // properties.Add(new JsonProperty
- // {
- // DeclaringType = type,
- // PropertyName = image.ToLower(),
- // UnderlyingName = image,
- // PropertyType = typeof(string),
- // Readable = true,
- // Writable = false,
- // ItemIsReference = false,
- // TypeNameHandling = TypeNameHandling.None,
- // ShouldSerialize = x =>
- // {
- // IThumbnails thumb = (IThumbnails)x;
- // return thumb?.Images?.ContainsKey(id) == true;
- // },
- // ValueProvider = new ThumbnailProvider(id)
- // });
+ // properties.Add(new JsonProperty
+ // {
+ // DeclaringType = type,
+ // PropertyName = image.ToLower(),
+ // UnderlyingName = image,
+ // PropertyType = typeof(string),
+ // Readable = true,
+ // Writable = false,
+ // ItemIsReference = false,
+ // TypeNameHandling = TypeNameHandling.None,
+ // ShouldSerialize = x =>
+ // {
+ // IThumbnails thumb = (IThumbnails)x;
+ // return thumb?.Images?.ContainsKey(id) == true;
+ // },
+ // ValueProvider = new ThumbnailProvider(id)
+ // });
// }
-
return properties;
}