So there was a small subtle issue with the notifications on Windows toast where the image wouldn't render correctly I changed it to the hero style which shows the album art way better
This commit is contained in:
+132
-9
@@ -40,6 +40,7 @@ namespace RadioDJViewer
|
||||
private string currentSongImagePath = string.Empty; // Path to the current song image
|
||||
private string defaultImagePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "default.jpg");
|
||||
private string mainImagesFolderPath = string.Empty; // New field for main images folder path
|
||||
private string _lastToastImagePath = string.Empty;
|
||||
private Profile loadedProfile = null; // Field to store the loaded profile
|
||||
private WidgetServer widgetServer = null; // Local widget HTTP server
|
||||
private bool widgetRunning = false;
|
||||
@@ -283,18 +284,16 @@ namespace RadioDJViewer
|
||||
}
|
||||
if (useFallback)
|
||||
{
|
||||
// Use fallback PNG from resources
|
||||
var fallbackImg = Properties.Resources.fallback;
|
||||
if (fallbackImg != null)
|
||||
{
|
||||
var resized = new Bitmap(fallbackImg, pictureBox1.Size);
|
||||
pictureBox1.Image = resized;
|
||||
currentSongImagePath = defaultImagePath;
|
||||
// Save fallback image to output folder as PNG
|
||||
if (!string.IsNullOrEmpty(outputFolderPath) && !string.IsNullOrEmpty(outputImageName))
|
||||
{
|
||||
string destPath = Path.Combine(outputFolderPath, Path.ChangeExtension(outputImageName, ".png"));
|
||||
resized.Save(destPath, System.Drawing.Imaging.ImageFormat.Png);
|
||||
SaveImageAsPng(resized, destPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -311,17 +310,15 @@ namespace RadioDJViewer
|
||||
var resized = new Bitmap(img, pictureBox1.Size);
|
||||
pictureBox1.Image = resized;
|
||||
currentSongImagePath = imagePath;
|
||||
// Save to output folder as PNG
|
||||
if (!string.IsNullOrEmpty(outputFolderPath) && !string.IsNullOrEmpty(outputImageName))
|
||||
{
|
||||
string destPath = Path.Combine(outputFolderPath, Path.ChangeExtension(outputImageName, ".png"));
|
||||
resized.Save(destPath, System.Drawing.Imaging.ImageFormat.Png);
|
||||
SaveImageAsPng(resized, destPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If loading image fails, fallback
|
||||
var fallbackImg = Properties.Resources.fallback;
|
||||
if (fallbackImg != null)
|
||||
{
|
||||
@@ -331,7 +328,7 @@ namespace RadioDJViewer
|
||||
if (!string.IsNullOrEmpty(outputFolderPath) && !string.IsNullOrEmpty(outputImageName))
|
||||
{
|
||||
string destPath = Path.Combine(outputFolderPath, Path.ChangeExtension(outputImageName, ".png"));
|
||||
resized.Save(destPath, System.Drawing.Imaging.ImageFormat.Png);
|
||||
SaveImageAsPng(resized, destPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -342,6 +339,131 @@ namespace RadioDJViewer
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveImageAsPng(Image image, string destinationPath)
|
||||
{
|
||||
if (image == null || string.IsNullOrWhiteSpace(destinationPath))
|
||||
return;
|
||||
|
||||
string directory = Path.GetDirectoryName(destinationPath);
|
||||
if (!string.IsNullOrWhiteSpace(directory))
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
string tempPath = destinationPath + ".tmp";
|
||||
using (var fileStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
image.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
fileStream.Flush(true);
|
||||
}
|
||||
|
||||
if (File.Exists(destinationPath))
|
||||
File.Delete(destinationPath);
|
||||
|
||||
File.Move(tempPath, destinationPath);
|
||||
}
|
||||
|
||||
private string BuildToastImagePath()
|
||||
{
|
||||
try
|
||||
{
|
||||
string sourcePath = currentSongImagePath;
|
||||
if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath))
|
||||
sourcePath = GetProfileOutputImagePath();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath))
|
||||
return string.Empty;
|
||||
|
||||
string toastDirectory = Path.Combine(Path.GetTempPath(), "RadioDJViewer", "ToastImages");
|
||||
Directory.CreateDirectory(toastDirectory);
|
||||
string toastPath = Path.Combine(toastDirectory, $"Album-Art-Hero-{DateTime.UtcNow.Ticks}.png");
|
||||
|
||||
using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
sourceStream.CopyTo(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
using (var sourceImage = Image.FromStream(memoryStream))
|
||||
using (var heroImage = CreateToastHeroCanvas(sourceImage))
|
||||
using (var fileStream = new FileStream(toastPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
heroImage.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
fileStream.Flush(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_lastToastImagePath) && !string.Equals(_lastToastImagePath, toastPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(_lastToastImagePath))
|
||||
File.Delete(_lastToastImagePath);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
_lastToastImagePath = toastPath;
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debug.WriteLine($"[Toast] Prepared 16:9 hero image '{toastPath}' from '{sourcePath}'");
|
||||
#endif
|
||||
return toastPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debug.WriteLine($"[Toast] Failed to prepare toast image: {ex}");
|
||||
#endif
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap CreateToastHeroCanvas(Image sourceImage)
|
||||
{
|
||||
const double targetAspectRatio = 16d / 9d;
|
||||
|
||||
int sourceWidth = Math.Max(sourceImage.Width, 1);
|
||||
int sourceHeight = Math.Max(sourceImage.Height, 1);
|
||||
double sourceAspectRatio = (double)sourceWidth / sourceHeight;
|
||||
|
||||
if (sourceWidth >= sourceHeight && Math.Abs(sourceAspectRatio - targetAspectRatio) < 0.01d)
|
||||
return new Bitmap(sourceImage);
|
||||
|
||||
int canvasWidth;
|
||||
int canvasHeight;
|
||||
|
||||
if (sourceAspectRatio < targetAspectRatio)
|
||||
{
|
||||
canvasHeight = sourceHeight;
|
||||
canvasWidth = (int)Math.Ceiling(canvasHeight * targetAspectRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
canvasWidth = sourceWidth;
|
||||
canvasHeight = (int)Math.Ceiling(canvasWidth / targetAspectRatio);
|
||||
}
|
||||
|
||||
canvasWidth = Math.Max(canvasWidth, sourceWidth);
|
||||
canvasHeight = Math.Max(canvasHeight, sourceHeight);
|
||||
|
||||
var heroCanvas = new Bitmap(canvasWidth, canvasHeight, PixelFormat.Format32bppArgb);
|
||||
using (var graphics = Graphics.FromImage(heroCanvas))
|
||||
{
|
||||
graphics.Clear(Color.Black);
|
||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||
|
||||
int x = (canvasWidth - sourceWidth) / 2;
|
||||
int y = (canvasHeight - sourceHeight) / 2;
|
||||
graphics.DrawImage(sourceImage, new Rectangle(x, y, sourceWidth, sourceHeight));
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debug.WriteLine($"[Toast] Hero canvas created: source={sourceWidth}x{sourceHeight}, canvas={canvasWidth}x{canvasHeight}");
|
||||
#endif
|
||||
return heroCanvas;
|
||||
}
|
||||
|
||||
private void PlaybackTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
UpdatePlaybackDisplay();
|
||||
@@ -838,7 +960,8 @@ namespace RadioDJViewer
|
||||
string safeArtist = string.IsNullOrWhiteSpace(artist) ? "No artist" : artist;
|
||||
DateTime now = DateTime.Now;
|
||||
string attribution = $"Date: {now:MM/dd/yyyy} | Time: {now:hh:mm tt}";
|
||||
ToastNotificationService.ShowTrackChangeToast(safeTitle, safeArtist, attribution, outputImagePath);
|
||||
string toastImagePath = BuildToastImagePath();
|
||||
ToastNotificationService.ShowTrackChangeToast(safeTitle, safeArtist, attribution, string.IsNullOrWhiteSpace(toastImagePath) ? outputImagePath : toastImagePath);
|
||||
}
|
||||
|
||||
private void HandleToastForTrackChange(string title, string artist)
|
||||
@@ -1014,7 +1137,7 @@ namespace RadioDJViewer
|
||||
string safeImage = SecurityElement.Escape(imageUri);
|
||||
string imageNode = string.IsNullOrWhiteSpace(safeImage)
|
||||
? string.Empty
|
||||
: $"<image placement='appLogoOverride' hint-crop='none' src='{safeImage}'/>";
|
||||
: $"<image placement='hero' src='{safeImage}' hint-crop='none'/>";
|
||||
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debug.WriteLine($"[Toast] Image URI used: '{imageUri}'");
|
||||
|
||||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.14.3")]
|
||||
[assembly: AssemblyFileVersion("1.14.3")]
|
||||
[assembly: AssemblyVersion("1.14.5")]
|
||||
[assembly: AssemblyFileVersion("1.14.5")]
|
||||
|
||||
Reference in New Issue
Block a user