diff options
Diffstat (limited to 'Emby.Drawing.Skia/SkiaEncoder.cs')
| -rw-r--r-- | Emby.Drawing.Skia/SkiaEncoder.cs | 181 |
1 files changed, 126 insertions, 55 deletions
diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs index 24f586d96..b5d6010b0 100644 --- a/Emby.Drawing.Skia/SkiaEncoder.cs +++ b/Emby.Drawing.Skia/SkiaEncoder.cs @@ -76,7 +76,7 @@ namespace Emby.Drawing.Skia private static bool IsTransparent(SKColor color) { - + return (color.Red == 255 && color.Green == 255 && color.Blue == 255) || color.Alpha == 0; } @@ -267,7 +267,7 @@ namespace Emby.Drawing.Skia { using (bitmap) { - return RotateAndFlip(bitmap, origin); + return OrientImage(bitmap, origin); } } } @@ -278,82 +278,153 @@ namespace Emby.Drawing.Skia return GetBitmap(path, cropWhitespace, false, out origin); } - private SKBitmap RotateAndFlip(SKBitmap original, SKCodecOrigin origin) + private SKBitmap OrientImage(SKBitmap bitmap, SKCodecOrigin origin) { - // these are the origins that represent a 90 degree turn in some fashion - var differentOrientations = new SKCodecOrigin[] + //var transformations = { + // 2: { rotate: 0, flip: true}, + // 3: { rotate: 180, flip: false}, + // 4: { rotate: 180, flip: true}, + // 5: { rotate: 90, flip: true}, + // 6: { rotate: 90, flip: false}, + // 7: { rotate: 270, flip: true}, + // 8: { rotate: 270, flip: false}, + //} + + switch (origin) { - SKCodecOrigin.LeftBottom, - SKCodecOrigin.LeftTop, - SKCodecOrigin.RightBottom, - SKCodecOrigin.RightTop - }; - // check if we need to turn the image - bool isDifferentOrientation = differentOrientations.Any(o => o == origin); + case SKCodecOrigin.TopRight: + { + var rotated = new SKBitmap(bitmap.Width, bitmap.Height); + using (var surface = new SKCanvas(rotated)) + { + surface.Translate(rotated.Width, 0); + surface.Scale(-1, 1); + surface.DrawBitmap(bitmap, 0, 0); + } - // define new width/height - var width = isDifferentOrientation ? original.Height : original.Width; - var height = isDifferentOrientation ? original.Width : original.Height; + return rotated; + } - var bitmap = new SKBitmap(width, height, true); + case SKCodecOrigin.BottomRight: + { + var rotated = new SKBitmap(bitmap.Width, bitmap.Height); + using (var surface = new SKCanvas(rotated)) + { + float px = bitmap.Width; + px /= 2; - // todo: the stuff in this switch statement should be rewritten to use pointers - switch (origin) - { - case SKCodecOrigin.LeftBottom: + float py = bitmap.Height; + py /= 2; - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(y, original.Width - 1 - x, original.GetPixel(x, y)); - break; + surface.RotateDegrees(180, px, py); + surface.DrawBitmap(bitmap, 0, 0); + } - case SKCodecOrigin.RightTop: + return rotated; + } - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(original.Height - 1 - y, x, original.GetPixel(x, y)); - break; + case SKCodecOrigin.BottomLeft: + { + var rotated = new SKBitmap(bitmap.Width, bitmap.Height); + using (var surface = new SKCanvas(rotated)) + { + float px = bitmap.Width; + px /= 2; - case SKCodecOrigin.RightBottom: + float py = bitmap.Height; + py /= 2; - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(original.Height - 1 - y, original.Width - 1 - x, original.GetPixel(x, y)); + surface.Translate(rotated.Width, 0); + surface.Scale(-1, 1); - break; + surface.RotateDegrees(180, px, py); + surface.DrawBitmap(bitmap, 0, 0); + } + + return rotated; + } case SKCodecOrigin.LeftTop: + { + // TODO: Remove dual canvases, had trouble with flipping + using (var rotated = new SKBitmap(bitmap.Height, bitmap.Width)) + { + using (var surface = new SKCanvas(rotated)) + { + surface.Translate(rotated.Width, 0); - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(y, x, original.GetPixel(x, y)); - break; + surface.RotateDegrees(90); - case SKCodecOrigin.BottomLeft: + surface.DrawBitmap(bitmap, 0, 0); - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(x, original.Height - 1 - y, original.GetPixel(x, y)); - break; + } - case SKCodecOrigin.BottomRight: + var flippedBitmap = new SKBitmap(rotated.Width, rotated.Height); + using (var flippedCanvas = new SKCanvas(flippedBitmap)) + { + flippedCanvas.Translate(flippedBitmap.Width, 0); + flippedCanvas.Scale(-1, 1); + flippedCanvas.DrawBitmap(rotated, 0, 0); + } - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(original.Width - 1 - x, original.Height - 1 - y, original.GetPixel(x, y)); - break; + return flippedBitmap; + } + } - case SKCodecOrigin.TopRight: + case SKCodecOrigin.RightTop: + { + var rotated = new SKBitmap(bitmap.Height, bitmap.Width); + using (var surface = new SKCanvas(rotated)) + { + surface.Translate(rotated.Width, 0); + surface.RotateDegrees(90); + surface.DrawBitmap(bitmap, 0, 0); + } - for (var x = 0; x < original.Width; x++) - for (var y = 0; y < original.Height; y++) - bitmap.SetPixel(original.Width - 1 - x, y, original.GetPixel(x, y)); - break; + return rotated; + } - } + case SKCodecOrigin.RightBottom: + { + // TODO: Remove dual canvases, had trouble with flipping + using (var rotated = new SKBitmap(bitmap.Height, bitmap.Width)) + { + using (var surface = new SKCanvas(rotated)) + { + surface.Translate(0, rotated.Height); + surface.RotateDegrees(270); + surface.DrawBitmap(bitmap, 0, 0); + } - return bitmap; + var flippedBitmap = new SKBitmap(rotated.Width, rotated.Height); + using (var flippedCanvas = new SKCanvas(flippedBitmap)) + { + flippedCanvas.Translate(flippedBitmap.Width, 0); + flippedCanvas.Scale(-1, 1); + flippedCanvas.DrawBitmap(rotated, 0, 0); + } + + return flippedBitmap; + } + } + + case SKCodecOrigin.LeftBottom: + { + var rotated = new SKBitmap(bitmap.Height, bitmap.Width); + using (var surface = new SKCanvas(rotated)) + { + surface.Translate(0, rotated.Height); + surface.RotateDegrees(270); + surface.DrawBitmap(bitmap, 0, 0); + } + + return rotated; + } + + default: + return bitmap; + } } public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) |
