Fix bug where book with corrupt image cannot be queued.
This commit is contained in:
parent
245e55782e
commit
5ec01913d5
@ -1,6 +1,8 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
using LibationAvalonia.Dialogs;
|
using LibationAvalonia.Dialogs;
|
||||||
|
using LibationFileManager;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace LibationAvalonia
|
namespace LibationAvalonia
|
||||||
@ -20,5 +22,21 @@ namespace LibationAvalonia
|
|||||||
=> dialogWindow.ShowDialog<DialogResult>(owner ?? App.MainWindow);
|
=> dialogWindow.ShowDialog<DialogResult>(owner ?? App.MainWindow);
|
||||||
|
|
||||||
public static Window GetParentWindow(this IControl control) => control.VisualRoot as Window;
|
public static Window GetParentWindow(this IControl control) => control.VisualRoot as Window;
|
||||||
|
|
||||||
|
|
||||||
|
private static Bitmap defaultImage;
|
||||||
|
public static Bitmap TryLoadImageOrDefault(byte[] picture, PictureSize defaultSize = PictureSize.Native)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var ms = new System.IO.MemoryStream(picture);
|
||||||
|
return new Bitmap(ms);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
using var ms = new System.IO.MemoryStream(PictureStorage.GetDefaultImage(defaultSize));
|
||||||
|
return defaultImage ??= new Bitmap(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using ApplicationServices;
|
using ApplicationServices;
|
||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
@ -10,7 +9,6 @@ using LibationAvalonia.ViewModels;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace LibationAvalonia.Dialogs
|
namespace LibationAvalonia.Dialogs
|
||||||
{
|
{
|
||||||
@ -112,8 +110,7 @@ namespace LibationAvalonia.Dialogs
|
|||||||
|
|
||||||
//init cover image
|
//init cover image
|
||||||
var picture = PictureStorage.GetPictureSynchronously(new PictureDefinition(libraryBook.Book.PictureId, PictureSize._80x80));
|
var picture = PictureStorage.GetPictureSynchronously(new PictureDefinition(libraryBook.Book.PictureId, PictureSize._80x80));
|
||||||
using var ms = new System.IO.MemoryStream(picture);
|
Cover = AvaloniaUtils.TryLoadImageOrDefault(picture, PictureSize._80x80);
|
||||||
Cover = new Bitmap(ms);
|
|
||||||
|
|
||||||
//init book details
|
//init book details
|
||||||
DetailsText = @$"
|
DetailsText = @$"
|
||||||
|
|||||||
@ -2,7 +2,6 @@ using Avalonia.Markup.Xaml;
|
|||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
|
|
||||||
@ -29,17 +28,7 @@ namespace LibationAvalonia.Dialogs
|
|||||||
|
|
||||||
public void SetCoverBytes(byte[] cover)
|
public void SetCoverBytes(byte[] cover)
|
||||||
{
|
{
|
||||||
try
|
_bitmapHolder.CoverImage = AvaloniaUtils.TryLoadImageOrDefault(cover);
|
||||||
{
|
|
||||||
var ms = new MemoryStream(cover);
|
|
||||||
_bitmapHolder.CoverImage = new Bitmap(ms);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Error(ex, "Error loading cover art for {file}", PictureFileName);
|
|
||||||
using var ms = App.OpenAsset("img-coverart-prod-unavailable_500x500.jpg");
|
|
||||||
_bitmapHolder.CoverImage = new Bitmap(ms);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void SaveImage_Clicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
public async void SaveImage_Clicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
|||||||
@ -8,28 +8,17 @@ namespace LibationAvalonia.ViewModels
|
|||||||
{
|
{
|
||||||
public class AvaloniaEntryStatus : EntryStatus, IEntryStatus, IComparable
|
public class AvaloniaEntryStatus : EntryStatus, IEntryStatus, IComparable
|
||||||
{
|
{
|
||||||
private static Bitmap _defaultImage;
|
|
||||||
public override IBrush BackgroundBrush => IsEpisode ? App.SeriesEntryGridBackgroundBrush : Brushes.Transparent;
|
public override IBrush BackgroundBrush => IsEpisode ? App.SeriesEntryGridBackgroundBrush : Brushes.Transparent;
|
||||||
|
|
||||||
private AvaloniaEntryStatus(LibraryBook libraryBook) : base(libraryBook) { }
|
private AvaloniaEntryStatus(LibraryBook libraryBook) : base(libraryBook) { }
|
||||||
public static EntryStatus Create(LibraryBook libraryBook) => new AvaloniaEntryStatus(libraryBook);
|
public static EntryStatus Create(LibraryBook libraryBook) => new AvaloniaEntryStatus(libraryBook);
|
||||||
|
|
||||||
protected override Bitmap LoadImage(byte[] picture)
|
protected override Bitmap LoadImage(byte[] picture)
|
||||||
{
|
=> AvaloniaUtils.TryLoadImageOrDefault(picture, LibationFileManager.PictureSize._80x80);
|
||||||
try
|
|
||||||
{
|
|
||||||
using var ms = new System.IO.MemoryStream(picture);
|
|
||||||
return new Bitmap(ms);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Error(ex, "Error loading cover art for {Book}", Book);
|
|
||||||
return _defaultImage ??= new Bitmap(App.OpenAsset("img-coverart-prod-unavailable_80x80.jpg"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Bitmap GetResourceImage(string rescName)
|
protected override Bitmap GetResourceImage(string rescName)
|
||||||
{
|
{
|
||||||
|
//These images are assest, so assume they will never corrupt.
|
||||||
using var stream = App.OpenAsset(rescName + ".png");
|
using var stream = App.OpenAsset(rescName + ".png");
|
||||||
return new Bitmap(stream);
|
return new Bitmap(stream);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,16 +115,14 @@ namespace LibationAvalonia.ViewModels
|
|||||||
PictureStorage.PictureCached += PictureStorage_PictureCached;
|
PictureStorage.PictureCached += PictureStorage_PictureCached;
|
||||||
|
|
||||||
// Mutable property. Set the field so PropertyChanged isn't fired.
|
// Mutable property. Set the field so PropertyChanged isn't fired.
|
||||||
using var ms = new System.IO.MemoryStream(picture);
|
_cover = AvaloniaUtils.TryLoadImageOrDefault(picture, PictureSize._80x80);
|
||||||
_cover = new Bitmap(ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)
|
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Definition.PictureId == LibraryBook.Book.PictureId)
|
if (e.Definition.PictureId == LibraryBook.Book.PictureId)
|
||||||
{
|
{
|
||||||
using var ms = new System.IO.MemoryStream(e.Picture);
|
Cover = AvaloniaUtils.TryLoadImageOrDefault(e.Picture, PictureSize._80x80);
|
||||||
Cover = new Bitmap(ms);
|
|
||||||
PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,7 +67,7 @@ namespace LibationFileManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
DownloadQueue.Add(def);
|
DownloadQueue.Add(def);
|
||||||
return (true, getDefaultImage(def.Size));
|
return (true, GetDefaultImage(def.Size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ namespace LibationFileManager
|
|||||||
|
|
||||||
public static void SetDefaultImage(PictureSize pictureSize, byte[] bytes)
|
public static void SetDefaultImage(PictureSize pictureSize, byte[] bytes)
|
||||||
=> defaultImages[pictureSize] = bytes;
|
=> defaultImages[pictureSize] = bytes;
|
||||||
private static byte[] getDefaultImage(PictureSize size)
|
public static byte[] GetDefaultImage(PictureSize size)
|
||||||
=> defaultImages.ContainsKey(size)
|
=> defaultImages.ContainsKey(size)
|
||||||
? defaultImages[size]
|
? defaultImages[size]
|
||||||
: new byte[0];
|
: new byte[0];
|
||||||
@ -120,7 +120,7 @@ namespace LibationFileManager
|
|||||||
private static byte[] downloadBytes(PictureDefinition def)
|
private static byte[] downloadBytes(PictureDefinition def)
|
||||||
{
|
{
|
||||||
if (def.PictureId is null)
|
if (def.PictureId is null)
|
||||||
return getDefaultImage(def.Size);
|
return GetDefaultImage(def.Size);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -135,7 +135,7 @@ namespace LibationFileManager
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return getDefaultImage(def.Size);
|
return GetDefaultImage(def.Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
@ -42,7 +41,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
this.Text = Book.Title;
|
this.Text = Book.Title;
|
||||||
|
|
||||||
(_, var picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80));
|
(_, var picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80));
|
||||||
this.coverPb.Image = Dinah.Core.WindowsDesktop.Drawing.ImageReader.ToImage(picture);
|
this.coverPb.Image = WinFormsUtil.TryLoadImageOrDefault(picture, PictureSize._80x80);
|
||||||
|
|
||||||
var t = @$"
|
var t = @$"
|
||||||
Title: {Book.Title}
|
Title: {Book.Title}
|
||||||
|
|||||||
@ -19,15 +19,7 @@ namespace LibationWinForms.GridView
|
|||||||
|
|
||||||
public void SetCoverArt(byte[] cover)
|
public void SetCoverArt(byte[] cover)
|
||||||
{
|
{
|
||||||
try
|
pictureBox1.Image = WinFormsUtil.TryLoadImageOrDefault(cover);
|
||||||
{
|
|
||||||
pictureBox1.Image = Dinah.Core.WindowsDesktop.Drawing.ImageReader.ToImage(cover);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Error(ex, "Error loading cover art for {file}", PictureFileName);
|
|
||||||
pictureBox1.Image = Properties.Resources.default_cover_500x500;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Make the form's aspect ratio always match the picture's aspect ratio.
|
#region Make the form's aspect ratio always match the picture's aspect ratio.
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core.WindowsDesktop.Drawing;
|
|
||||||
using LibationUiBase.GridView;
|
using LibationUiBase.GridView;
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace LibationWinForms.GridView
|
namespace LibationWinForms.GridView
|
||||||
@ -14,23 +12,12 @@ namespace LibationWinForms.GridView
|
|||||||
private WinFormsEntryStatus(LibraryBook libraryBook) : base(libraryBook) { }
|
private WinFormsEntryStatus(LibraryBook libraryBook) : base(libraryBook) { }
|
||||||
public static EntryStatus Create(LibraryBook libraryBook) => new WinFormsEntryStatus(libraryBook);
|
public static EntryStatus Create(LibraryBook libraryBook) => new WinFormsEntryStatus(libraryBook);
|
||||||
|
|
||||||
protected override object LoadImage(byte[] picture)
|
protected override Image LoadImage(byte[] picture)
|
||||||
{
|
=> WinFormsUtil.TryLoadImageOrDefault(picture, LibationFileManager.PictureSize._80x80);
|
||||||
try
|
|
||||||
{
|
|
||||||
return ImageReader.ToImage(picture);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Error(ex, "Error loading cover art for {Book}", Book);
|
|
||||||
return Properties.Resources.default_cover_80x80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Image GetResourceImage(string rescName)
|
protected override Image GetResourceImage(string rescName)
|
||||||
{
|
{
|
||||||
var image = Properties.Resources.ResourceManager.GetObject(rescName);
|
var image = Properties.Resources.ResourceManager.GetObject(rescName);
|
||||||
|
|
||||||
return image as Bitmap;
|
return image as Bitmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,6 @@ using AudibleApi;
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
using Dinah.Core.ErrorHandling;
|
using Dinah.Core.ErrorHandling;
|
||||||
using Dinah.Core.WindowsDesktop.Drawing;
|
|
||||||
using FileLiberator;
|
using FileLiberator;
|
||||||
using LibationFileManager;
|
using LibationFileManager;
|
||||||
using LibationUiBase;
|
using LibationUiBase;
|
||||||
@ -87,7 +86,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
|
|
||||||
if (isDefault)
|
if (isDefault)
|
||||||
PictureStorage.PictureCached += PictureStorage_PictureCached;
|
PictureStorage.PictureCached += PictureStorage_PictureCached;
|
||||||
_cover = ImageReader.ToImage(picture);
|
_cover = WinFormsUtil.TryLoadImageOrDefault(picture, PictureSize._80x80); ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +94,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
{
|
{
|
||||||
if (e.Definition.PictureId == LibraryBook.Book.PictureId)
|
if (e.Definition.PictureId == LibraryBook.Book.PictureId)
|
||||||
{
|
{
|
||||||
Cover = ImageReader.ToImage(e.Picture);
|
Cover = WinFormsUtil.TryLoadImageOrDefault(e.Picture, PictureSize._80x80);
|
||||||
PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,7 +259,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
|
|
||||||
private void AudioDecodable_CoverImageDiscovered(object sender, byte[] coverArt)
|
private void AudioDecodable_CoverImageDiscovered(object sender, byte[] coverArt)
|
||||||
{
|
{
|
||||||
Cover = ImageReader.ToImage(coverArt);
|
Cover = WinFormsUtil.TryLoadImageOrDefault(coverArt, PictureSize._80x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
23
Source/LibationWinForms/WinFormsUtil.cs
Normal file
23
Source/LibationWinForms/WinFormsUtil.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Dinah.Core.WindowsDesktop.Drawing;
|
||||||
|
using LibationFileManager;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace LibationWinForms
|
||||||
|
{
|
||||||
|
internal static class WinFormsUtil
|
||||||
|
{
|
||||||
|
private static Bitmap defaultImage;
|
||||||
|
public static Image TryLoadImageOrDefault(byte[] picture, PictureSize defaultSize = PictureSize.Native)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ImageReader.ToImage(picture);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
using var ms = new System.IO.MemoryStream(PictureStorage.GetDefaultImage(defaultSize));
|
||||||
|
return defaultImage ??= new Bitmap(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user