using System.Security.Cryptography; namespace Harmonia.Core.Imaging; public class SongPictureInfo { public required byte[] Data { get; init; } public string? ImageHash { get; private set; } public required string ImageName { get; init; } public long Size => Data.Length; private SongPictureInfo() { } public static async Task FromStreamAsync(Stream stream, CancellationToken cancellationToken) { string imageHash = ComputeImageHash(stream); return await GetSongPictureInfoAsync(stream, "Embedded", imageHash, cancellationToken); } private static string ComputeImageHash(Stream stream) { using var md5 = MD5.Create(); byte[] hash = md5.ComputeHash(stream); return Convert.ToHexStringLower(hash); } public static async Task FromFileAsync(string fileName, CancellationToken cancellationToken) { using FileStream fileStream = File.OpenRead(fileName); return await GetSongPictureInfoAsync(fileStream, fileName, cancellationToken: cancellationToken); } private static async Task GetSongPictureInfoAsync(Stream stream, string imageName, string? imageHash = null, CancellationToken cancellationToken = default) { return new() { Data = await GetImageDataAsync(stream, cancellationToken), ImageHash = imageHash, ImageName = imageName }; } public static async Task GetImageDataAsync(Stream stream, CancellationToken cancellationToken) { stream.Seek(0, SeekOrigin.Begin); using MemoryStream memoryStream = new(); await stream.CopyToAsync(memoryStream, cancellationToken); return memoryStream.ToArray(); } }