internal static SKBitmap Decode(string path, bool forceCleanBitmap, out SKCodecOrigin origin) { var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); if (requiresTransparencyHack || forceCleanBitmap) { using (var stream = new SKFileStream(path)) { using (var codec = SKCodec.Create(stream)) { if (codec == null) { origin = SKCodecOrigin.TopLeft; return(null); } // create the bitmap var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack); if (bitmap != null) { // decode codec.GetPixels(bitmap.Info, bitmap.GetPixels()); origin = codec.Origin; } else { origin = SKCodecOrigin.TopLeft; } return(bitmap); } } } var resultBitmap = SKBitmap.Decode(path); if (resultBitmap == null) { return(Decode(path, true, out origin)); } // If we have to resize these they often end up distorted if (resultBitmap.ColorType == SKColorType.Gray8) { using (resultBitmap) { return(Decode(path, true, out origin)); } } origin = SKCodecOrigin.TopLeft; return(resultBitmap); }
// Got the code from https://stackoverflow.com/a/45620498/1074470 private static SKBitmap HandleOrientation(SKBitmap bitmap, SKCodecOrigin orientation) { SKBitmap rotated; switch (orientation) { case SKCodecOrigin.BottomRight: using (var surface = new SKCanvas(bitmap)) { surface.RotateDegrees(180, bitmap.Width / 2, bitmap.Height / 2); surface.DrawBitmap(bitmap.Copy(), 0, 0); } return(bitmap); case SKCodecOrigin.RightTop: 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); } return(rotated); case SKCodecOrigin.LeftBottom: 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); } }
private SKBitmap LoadBitmap(Stream stream, out SKCodecOrigin origin) { using (var s = new SKManagedStream(stream)) { using (var codec = SKCodec.Create(s)) { origin = codec.Origin; var info = codec.Info; var bitmap = new SKBitmap(info.Width, info.Height, SKImageInfo.PlatformColorType, info.IsOpaque ? SKAlphaType.Opaque : SKAlphaType.Premul); var result = codec.GetPixels(bitmap.Info, bitmap.GetPixels(out _)); if (result == SKCodecResult.Success || result == SKCodecResult.IncompleteInput) { return(bitmap); } else { throw new ArgumentException("Unable to load bitmap from provided data"); } } } }
private SKBitmap RotateAndFlip(SKBitmap original, SKCodecOrigin origin) { // these are the origins that represent a 90 degree turn in some fashion var differentOrientations = new SKCodecOrigin[] { SKCodecOrigin.LeftBottom, SKCodecOrigin.LeftTop, SKCodecOrigin.RightBottom, SKCodecOrigin.RightTop }; // check if we need to turn the image bool isDifferentOrientation = differentOrientations.Any(o => o == origin); // define new width/height var width = isDifferentOrientation ? original.Height : original.Width; var height = isDifferentOrientation ? original.Width : original.Height; var bitmap = new SKBitmap(width, height, original.AlphaType == SKAlphaType.Opaque); // todo: the stuff in this switch statement should be rewritten to use pointers switch (origin) { case SKCodecOrigin.LeftBottom: 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; case SKCodecOrigin.RightTop: 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.RightBottom: 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)); } } break; case SKCodecOrigin.LeftTop: 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; case SKCodecOrigin.BottomLeft: 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: 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; case SKCodecOrigin.TopRight: 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; } original.Dispose(); return(bitmap); }
private SKBitmap OrientImage(SKBitmap bitmap, SKCodecOrigin origin) { //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) { 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); } return(rotated); } case SKCodecOrigin.BottomRight: { var rotated = new SKBitmap(bitmap.Width, bitmap.Height); using (var surface = new SKCanvas(rotated)) { float px = bitmap.Width; px /= 2; float py = bitmap.Height; py /= 2; surface.RotateDegrees(180, px, py); surface.DrawBitmap(bitmap, 0, 0); } return(rotated); } case SKCodecOrigin.BottomLeft: { var rotated = new SKBitmap(bitmap.Width, bitmap.Height); using (var surface = new SKCanvas(rotated)) { float px = bitmap.Width; px /= 2; float py = bitmap.Height; py /= 2; surface.Translate(rotated.Width, 0); surface.Scale(-1, 1); 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); surface.RotateDegrees(90); surface.DrawBitmap(bitmap, 0, 0); } 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.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); } 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); } 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); } }
private SKBitmap GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBitmap, ImageOrientation?orientation, out SKCodecOrigin origin) { if (cropWhitespace) { using (var bitmap = Decode(path, forceAnalyzeBitmap, _fileSystem, orientation, out origin)) { return(CropWhiteSpace(bitmap)); } } return(Decode(path, forceAnalyzeBitmap, _fileSystem, orientation, out origin)); }
internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem fileSystem, ImageOrientation?orientation, out SKCodecOrigin origin) { if (!fileSystem.FileExists(path)) { throw new FileNotFoundException("File not found", path); } var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); if (requiresTransparencyHack || forceCleanBitmap) { using (var stream = new SKFileStream(NormalizePath(path, fileSystem))) { using (var codec = SKCodec.Create(stream)) { if (codec == null) { origin = GetSKCodecOrigin(orientation); return(null); } // create the bitmap var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack); if (bitmap != null) { // decode codec.GetPixels(bitmap.Info, bitmap.GetPixels()); origin = codec.Origin; } else { origin = GetSKCodecOrigin(orientation); } return(bitmap); } } } var resultBitmap = SKBitmap.Decode(NormalizePath(path, fileSystem)); if (resultBitmap == null) { return(Decode(path, true, fileSystem, orientation, out origin)); } // If we have to resize these they often end up distorted if (resultBitmap.ColorType == SKColorType.Gray8) { using (resultBitmap) { return(Decode(path, true, fileSystem, orientation, out origin)); } } origin = SKCodecOrigin.TopLeft; return(resultBitmap); }