|
@@ -269,14 +269,24 @@ public class SkiaEncoder : IImageEncoder
|
|
}
|
|
}
|
|
|
|
|
|
// create the bitmap
|
|
// create the bitmap
|
|
- var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack);
|
|
|
|
|
|
+ SKBitmap? bitmap = null;
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack);
|
|
|
|
|
|
- // decode
|
|
|
|
- _ = codec.GetPixels(bitmap.Info, bitmap.GetPixels());
|
|
|
|
|
|
+ // decode
|
|
|
|
+ _ = codec.GetPixels(bitmap.Info, bitmap.GetPixels());
|
|
|
|
|
|
- origin = codec.EncodedOrigin;
|
|
|
|
|
|
+ origin = codec.EncodedOrigin;
|
|
|
|
|
|
- return bitmap;
|
|
|
|
|
|
+ return bitmap!;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogError(e, "Detected intermediary error decoding image {0}", path);
|
|
|
|
+ bitmap?.Dispose();
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
var resultBitmap = SKBitmap.Decode(NormalizePath(path));
|
|
var resultBitmap = SKBitmap.Decode(NormalizePath(path));
|
|
@@ -286,17 +296,26 @@ public class SkiaEncoder : IImageEncoder
|
|
return Decode(path, true, orientation, out origin);
|
|
return Decode(path, true, orientation, out origin);
|
|
}
|
|
}
|
|
|
|
|
|
- // If we have to resize these they often end up distorted
|
|
|
|
- if (resultBitmap.ColorType == SKColorType.Gray8)
|
|
|
|
|
|
+ try
|
|
{
|
|
{
|
|
- using (resultBitmap)
|
|
|
|
|
|
+ // If we have to resize these they often end up distorted
|
|
|
|
+ if (resultBitmap.ColorType == SKColorType.Gray8)
|
|
{
|
|
{
|
|
- return Decode(path, true, orientation, out origin);
|
|
|
|
|
|
+ using (resultBitmap)
|
|
|
|
+ {
|
|
|
|
+ return Decode(path, true, orientation, out origin);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- origin = SKEncodedOrigin.TopLeft;
|
|
|
|
- return resultBitmap;
|
|
|
|
|
|
+ origin = SKEncodedOrigin.TopLeft;
|
|
|
|
+ return resultBitmap;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogError(e, "Detected intermediary error decoding image {0}", path);
|
|
|
|
+ resultBitmap?.Dispose();
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private SKBitmap? GetBitmap(string path, bool autoOrient, ImageOrientation? orientation)
|
|
private SKBitmap? GetBitmap(string path, bool autoOrient, ImageOrientation? orientation)
|
|
@@ -335,58 +354,78 @@ public class SkiaEncoder : IImageEncoder
|
|
var width = (int)Math.Round(svg.Drawable.Bounds.Width);
|
|
var width = (int)Math.Round(svg.Drawable.Bounds.Width);
|
|
var height = (int)Math.Round(svg.Drawable.Bounds.Height);
|
|
var height = (int)Math.Round(svg.Drawable.Bounds.Height);
|
|
|
|
|
|
- var bitmap = new SKBitmap(width, height);
|
|
|
|
- using var canvas = new SKCanvas(bitmap);
|
|
|
|
- canvas.DrawPicture(svg.Picture);
|
|
|
|
- canvas.Flush();
|
|
|
|
- canvas.Save();
|
|
|
|
|
|
+ SKBitmap? bitmap = null;
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ bitmap = new SKBitmap(width, height);
|
|
|
|
+ using var canvas = new SKCanvas(bitmap);
|
|
|
|
+ canvas.DrawPicture(svg.Picture);
|
|
|
|
+ canvas.Flush();
|
|
|
|
+ canvas.Save();
|
|
|
|
|
|
- return bitmap;
|
|
|
|
|
|
+ return bitmap!;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogError(e, "Detected intermediary error extracting image {0}", path);
|
|
|
|
+ bitmap?.Dispose();
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private SKBitmap OrientImage(SKBitmap bitmap, SKEncodedOrigin origin)
|
|
private SKBitmap OrientImage(SKBitmap bitmap, SKEncodedOrigin origin)
|
|
{
|
|
{
|
|
var needsFlip = origin is SKEncodedOrigin.LeftBottom or SKEncodedOrigin.LeftTop or SKEncodedOrigin.RightBottom or SKEncodedOrigin.RightTop;
|
|
var needsFlip = origin is SKEncodedOrigin.LeftBottom or SKEncodedOrigin.LeftTop or SKEncodedOrigin.RightBottom or SKEncodedOrigin.RightTop;
|
|
- var rotated = needsFlip
|
|
|
|
- ? new SKBitmap(bitmap.Height, bitmap.Width)
|
|
|
|
- : new SKBitmap(bitmap.Width, bitmap.Height);
|
|
|
|
- using var surface = new SKCanvas(rotated);
|
|
|
|
- var midX = (float)rotated.Width / 2;
|
|
|
|
- var midY = (float)rotated.Height / 2;
|
|
|
|
-
|
|
|
|
- switch (origin)
|
|
|
|
- {
|
|
|
|
- case SKEncodedOrigin.TopRight:
|
|
|
|
- surface.Scale(-1, 1, midX, midY);
|
|
|
|
- break;
|
|
|
|
- case SKEncodedOrigin.BottomRight:
|
|
|
|
- surface.RotateDegrees(180, midX, midY);
|
|
|
|
- break;
|
|
|
|
- case SKEncodedOrigin.BottomLeft:
|
|
|
|
- surface.Scale(1, -1, midX, midY);
|
|
|
|
- break;
|
|
|
|
- case SKEncodedOrigin.LeftTop:
|
|
|
|
- surface.Translate(0, -rotated.Height);
|
|
|
|
- surface.Scale(1, -1, midX, midY);
|
|
|
|
- surface.RotateDegrees(-90);
|
|
|
|
- break;
|
|
|
|
- case SKEncodedOrigin.RightTop:
|
|
|
|
- surface.Translate(rotated.Width, 0);
|
|
|
|
- surface.RotateDegrees(90);
|
|
|
|
- break;
|
|
|
|
- case SKEncodedOrigin.RightBottom:
|
|
|
|
- surface.Translate(rotated.Width, 0);
|
|
|
|
- surface.Scale(1, -1, midX, midY);
|
|
|
|
- surface.RotateDegrees(90);
|
|
|
|
- break;
|
|
|
|
- case SKEncodedOrigin.LeftBottom:
|
|
|
|
- surface.Translate(0, rotated.Height);
|
|
|
|
- surface.RotateDegrees(-90);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- surface.DrawBitmap(bitmap, 0, 0);
|
|
|
|
- return rotated;
|
|
|
|
|
|
+ SKBitmap? rotated = null;
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ rotated = needsFlip
|
|
|
|
+ ? new SKBitmap(bitmap.Height, bitmap.Width)
|
|
|
|
+ : new SKBitmap(bitmap.Width, bitmap.Height);
|
|
|
|
+ using var surface = new SKCanvas(rotated);
|
|
|
|
+ var midX = (float)rotated.Width / 2;
|
|
|
|
+ var midY = (float)rotated.Height / 2;
|
|
|
|
+
|
|
|
|
+ switch (origin)
|
|
|
|
+ {
|
|
|
|
+ case SKEncodedOrigin.TopRight:
|
|
|
|
+ surface.Scale(-1, 1, midX, midY);
|
|
|
|
+ break;
|
|
|
|
+ case SKEncodedOrigin.BottomRight:
|
|
|
|
+ surface.RotateDegrees(180, midX, midY);
|
|
|
|
+ break;
|
|
|
|
+ case SKEncodedOrigin.BottomLeft:
|
|
|
|
+ surface.Scale(1, -1, midX, midY);
|
|
|
|
+ break;
|
|
|
|
+ case SKEncodedOrigin.LeftTop:
|
|
|
|
+ surface.Translate(0, -rotated.Height);
|
|
|
|
+ surface.Scale(1, -1, midX, midY);
|
|
|
|
+ surface.RotateDegrees(-90);
|
|
|
|
+ break;
|
|
|
|
+ case SKEncodedOrigin.RightTop:
|
|
|
|
+ surface.Translate(rotated.Width, 0);
|
|
|
|
+ surface.RotateDegrees(90);
|
|
|
|
+ break;
|
|
|
|
+ case SKEncodedOrigin.RightBottom:
|
|
|
|
+ surface.Translate(rotated.Width, 0);
|
|
|
|
+ surface.Scale(1, -1, midX, midY);
|
|
|
|
+ surface.RotateDegrees(90);
|
|
|
|
+ break;
|
|
|
|
+ case SKEncodedOrigin.LeftBottom:
|
|
|
|
+ surface.Translate(0, rotated.Height);
|
|
|
|
+ surface.RotateDegrees(-90);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ surface.DrawBitmap(bitmap, 0, 0);
|
|
|
|
+ return rotated;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogError(e, "Detected intermediary error rotating image");
|
|
|
|
+ rotated?.Dispose();
|
|
|
|
+ throw;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -562,7 +601,7 @@ public class SkiaEncoder : IImageEncoder
|
|
// Only generate the splash screen if we have at least one poster and at least one backdrop/thumbnail.
|
|
// Only generate the splash screen if we have at least one poster and at least one backdrop/thumbnail.
|
|
if (posters.Count > 0 && backdrops.Count > 0)
|
|
if (posters.Count > 0 && backdrops.Count > 0)
|
|
{
|
|
{
|
|
- var splashBuilder = new SplashscreenBuilder(this);
|
|
|
|
|
|
+ var splashBuilder = new SplashscreenBuilder(this, _logger);
|
|
var outputPath = Path.Combine(_appPaths.DataPath, "splashscreen.png");
|
|
var outputPath = Path.Combine(_appPaths.DataPath, "splashscreen.png");
|
|
splashBuilder.GenerateSplash(posters, backdrops, outputPath);
|
|
splashBuilder.GenerateSplash(posters, backdrops, outputPath);
|
|
}
|
|
}
|