|
|
|
@ -269,14 +269,24 @@ public class SkiaEncoder : IImageEncoder
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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));
|
|
|
|
@ -286,17 +296,26 @@ public class SkiaEncoder : IImageEncoder
|
|
|
|
|
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)
|
|
|
|
@ -335,58 +354,78 @@ public class SkiaEncoder : IImageEncoder
|
|
|
|
|
var width = (int)Math.Round(svg.Drawable.Bounds.Width);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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>
|
|
|
|
@ -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.
|
|
|
|
|
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");
|
|
|
|
|
splashBuilder.GenerateSplash(posters, backdrops, outputPath);
|
|
|
|
|
}
|
|
|
|
|