Exemple #1
0
        private void CreateResizedImage()
        {
            using var image = _surface.Snapshot();
            var boundary = SKRectI.Create(0, 0, Width, Height);

            Result = image.Subset(boundary);
        }
        async Task ProcessImage(MediaFile image)
        {
            if (image != null)
            {
                //ImageCollection.Add(image);

                //if (this.PhotoCommandParameter.PhotoType == PhotoTypes.CUSTOMER_PHOTO)
                //{
                var bitmap   = SKBitmap.Decode(image.GetStreamWithImageRotatedForExternalStorage());
                var altImage = SKImage.FromBitmap(bitmap);
                var length   = Math.Min(bitmap.Width, bitmap.Height);
                var subset   = altImage.Subset(SKRectI.Create((bitmap.Width - length) / 2, (bitmap.Height - length) / 2, length, length));

                ImageStream = subset.Encode(SKEncodedImageFormat.Jpeg, 100).AsStream();
                //}
                //else
                //{
                //    ImageStream = image.GetStreamWithImageRotatedForExternalStorage();
                //}

                IsAcceptVisible = true;

                try
                {
                    // TODO: load image from Azure
                    //ImageSource = AzureStorage.GetImageSource(ImageStream);
                }
                catch //(Exception ex)
                {
                    //Logger.I.LogError(ex, "An error occured while processing the image");
                }
            }
        }
        private void Initialize(IEnumerable <Layer> layers, string undoChangeLocation, bool saveOnStartup, bool useDocumentSize = false)
        {
            var layersArray = layers as Layer[] ?? layers.ToArray();

            LayerChunk[] layerChunks = new LayerChunk[layersArray.Length];
            for (var i = 0; i < layersArray.Length; i++)
            {
                var layer   = layersArray[i];
                int width   = layer.Width;
                int height  = layer.Height;
                int offsetX = layer.OffsetX;
                int offsetY = layer.OffsetY;

                if (useDocumentSize)
                {
                    width   = layer.MaxWidth;
                    height  = layer.MaxHeight;
                    offsetX = 0;
                    offsetY = 0;
                }

                layerChunks[i] = new LayerChunk(layer, SKRectI.Create(offsetX, offsetY, width, height));
                layersToStore.Add(layer.GuidValue);
            }

            UndoChangeLocation = undoChangeLocation;
            GenerateUndoLayers(layerChunks);
            if (saveOnStartup)
            {
                SaveLayersOnDevice();
            }
        }
        protected void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            canvas.Clear(SKColors.White);

            // decode the bitmap
            var desiredInfo = new SKImageInfo(386, 395, SKImageInfo.PlatformColorType, SKAlphaType.Premul);

            using (var stream = new SKManagedStream(SampleMedia.Images.BabyTux))
                using (var bitmap = SKBitmap.Decode(stream, desiredInfo))
                {
                    // draw directly on the bitmap
                    using (var annotationCanvas = new SKCanvas(bitmap))
                        using (var paint = new SKPaint())
                        {
                            paint.StrokeWidth = 3;
                            paint.Color       = SampleMedia.Colors.XamarinLightBlue;
                            paint.Style       = SKPaintStyle.Stroke;

                            var face = SKRectI.Create(100, 50, 190, 170);
                            annotationCanvas.DrawRect(face, paint);
                        }

                    // draw the modified bitmap to the screen
                    canvas.DrawBitmap(bitmap, 10, 10);
                }
        }
Exemple #5
0
        public void Crop(int size)
        {
            int width, height;

            if (_bitmap.Width > _bitmap.Height)
            {
                height = size;
                width  = _bitmap.Width * size / _bitmap.Height;
            }
            else
            {
                width  = size;
                height = _bitmap.Height * size / _bitmap.Width;
            }

            using (var resizedBitmap = _bitmap.Resize(new SKImageInfo(width, height), SKFilterQuality.High))
            {
                int x = (width - size) / 2;
                int y = (height - size) / 2;

                var image = SKImage.FromBitmap(resizedBitmap);
                _image  = image.Subset(SKRectI.Create(x, y, size, size));
                _bitmap = SKBitmap.FromImage(_image);
            }
        }
Exemple #6
0
        public static SKBitmap CropImageAtMidPoint(SKBitmap inImg)
        {
            int w           = inImg.Width;
            int h           = inImg.Height;
            int shortestLen = 0;
            int longestLen  = 0;
            int x           = 0;
            int y           = 0;

            if (w < h)
            {
                shortestLen = w;
                longestLen  = h;
                x           = 0;
                y           = (h - w) / 2;
            }
            else if (h < w)
            {
                shortestLen = h;
                longestLen  = w;
                y           = 0;
                x           = (w - h) / 2;
            }
            else
            {
                // already square. return.
                return(inImg);
            }
            SKRectI  square   = SKRectI.Create(x, y, shortestLen, shortestLen);
            SKBitmap finalBmp = new SKBitmap(shortestLen, shortestLen);

            Debug.WriteLine("DHB:GlobalSingletonHelpers:rotateAndCrop pre extract");
            inImg.ExtractSubset(finalBmp, square);
            return(finalBmp);
        }
Exemple #7
0
        private static byte[] CreateThumbnail(Pattern pattern, int thumbnailWidth, int thumbnailHeight)
        {
            var size   = GetStitchSize((int)pattern.Width, (int)pattern.Height, thumbnailWidth, thumbnailHeight);
            var width  = pattern.Width * size;
            var height = pattern.Height * size;
            var bitmap = new SKBitmap((int)width, (int)height);
            var canvas = new SKCanvas(bitmap);

            canvas.Clear();

            foreach (var stitch in pattern.Stitches)
            {
                var configuration = pattern.Configurations[stitch.ConfigurationIndex];
                var paint         = new SKPaint {
                    Color = SKColor.Parse(configuration.HexColor)
                };
                var rect = new SKRect
                {
                    Left   = stitch.X * size,
                    Top    = stitch.Y * size,
                    Right  = (stitch.X + 1) * size,
                    Bottom = (stitch.Y + 1) * size
                };
                canvas.DrawRect(rect, paint);
            }

            var x     = (int)(width - thumbnailWidth) / 2;
            var y     = (int)(height - thumbnailHeight) / 2;
            var image = SKImage.FromBitmap(bitmap).Subset(SKRectI.Create(x, y, thumbnailWidth, thumbnailHeight));

            return(image.Encode(SKEncodedImageFormat.Png, 100).ToArray());
        }
        // Preprocess the quadrants of the input image
        public void ProcessInputImageColors(int tileWidth, int tileHeight)
        {
            using (var skStream = new SKManagedStream(inputStream))
                using (var bitmap = SKBitmap.Decode(skStream)) {
                    int xTileCount = bitmap.Width / tileWidth;
                    int yTileCount = bitmap.Height / tileHeight;

                    int tileDivisionWidth  = tileWidth / quadrantDivisionCount;
                    int tileDivisionHeight = tileHeight / quadrantDivisionCount;

                    int quadrantsCompleted = 0;
                    int quadrantsTotal     = xTileCount * yTileCount * quadrantDivisionCount * quadrantDivisionCount;
                    inputImageRGBGrid = new SKColor[xTileCount, yTileCount][, ];

                    //Divide the input image into separate tile sections and calculate the average pixel value for each one
                    for (int yTileIndex = 0; yTileIndex < yTileCount; yTileIndex++)
                    {
                        for (int xTileIndex = 0; xTileIndex < xTileCount; xTileIndex++)
                        {
                            var rect = SKRectI.Create(xTileIndex * tileWidth, yTileIndex * tileHeight, tileWidth, tileHeight);
                            inputImageRGBGrid[xTileIndex, yTileIndex] = GetAverageColorGrid(bitmap, rect);
                            quadrantsCompleted += (quadrantDivisionCount * quadrantDivisionCount);
                        }
                    }
                }
        }
Exemple #9
0
        private void InitializeStorageBasedChange(SKRectI toolSessionRect)
        {
            Document doc       = ViewModels.ViewModelMain.Current.BitmapManager.ActiveDocument;
            var      toolSize  = Toolbar.GetSetting <SizeSetting>("ToolSize");
            SKRectI  finalRect = toolSessionRect;

            if (toolSize != null && toolSize.Value > 1)
            {
                int halfSize = (int)Math.Ceiling(toolSize.Value / 2f);
                finalRect.Inflate(halfSize, halfSize);
            }

            if (toolSessionRect.IsEmpty)
            {
                finalRect = SKRectI.Create(doc.ActiveLayer.OffsetX, doc.ActiveLayer.OffsetY, doc.ActiveLayer.Width, doc.ActiveLayer.Height);
            }

            if (UseDocumentRectForUndo)
            {
                finalRect = SKRectI.Create(0, 0, doc.Width, doc.Height);
            }

            if (_customRectReported)
            {
                _customRectReported = false;
                finalRect           = _rectReportedByTool;
                _rectReportedByTool = SKRectI.Empty;
            }

            _change = new StorageBasedChange(doc, new[] { new LayerChunk(doc.ActiveLayer, finalRect) });
        }
        public void SaveLayersOnDevice()
        {
            int i = 0;

            foreach (var layerGuid in layersToStore)
            {
                Layer     layer       = Document.Layers.First(x => x.GuidValue == layerGuid);
                UndoLayer storedLayer = StoredLayers[i];
                if (Directory.Exists(Path.GetDirectoryName(storedLayer.StoredPngLayerName)))
                {
                    // Calculate absolute rect to relative rect
                    SKRectI finalRect = SKRectI.Create(
                        storedLayer.SerializedRect.Left - layer.OffsetX,
                        storedLayer.SerializedRect.Top - layer.OffsetY,
                        storedLayer.SerializedRect.Width,
                        storedLayer.SerializedRect.Height);

                    using var image = layer.LayerBitmap.SkiaSurface.Snapshot();
                    using Surface targetSizeSurface = new Surface(finalRect.Width, finalRect.Height);

                    targetSizeSurface.SkiaSurface.Canvas.DrawImage(image, finalRect, SKRect.Create(0, 0, finalRect.Width, finalRect.Height), Surface.ReplacingPaint);

                    //DebugSavePng(targetSizeSurface, storedLayer);

                    Exporter.SaveAsGZippedBytes(storedLayer.StoredPngLayerName, targetSizeSurface);
                }

                i++;
            }

            layersToStore = new List <Guid>();
        }
Exemple #11
0
        public void RectIteratorHasCorrectRects()
        {
            var rectA = SKRectI.Create(10, 10, 100, 100);
            var rectB = SKRectI.Create(50, 50, 100, 100);

            using var region = new SKRegion(rectA);
            region.Op(rectB, SKRegionOperation.Union);

            using var iterator = region.CreateRectIterator();

            Assert.True(iterator.Next(out var rect));
            Assert.Equal(SKRectI.Create(10, 10, 100, 40), rect);

            Assert.True(iterator.Next(out rect));
            Assert.Equal(SKRectI.Create(10, 50, 140, 60), rect);

            Assert.True(iterator.Next(out rect));
            Assert.Equal(SKRectI.Create(50, 110, 100, 40), rect);

            Assert.False(iterator.Next(out rect));
            Assert.Equal(SKRect.Empty, rect);

            Assert.False(iterator.Next(out rect));
            Assert.Equal(SKRect.Empty, rect);
        }
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            canvas.Clear(SKColors.White);

            if (bitmap != null)
            {
                var bmpRect = SKRectI.Create(width, height).AspectFit(bitmap.Info.Size);

                using (var resized = new SKBitmap(bmpRect.Width, bmpRect.Height))
                    using (var paint = new SKPaint())
                    {
                        bitmap.Resize(resized, method);

                        canvas.DrawBitmap(resized, bmpRect);

                        paint.TextAlign   = SKTextAlign.Center;
                        paint.TextSize    = 36;
                        paint.IsAntialias = true;

                        paint.Color = new SKColor(0, 0, 0, 127);
                        canvas.DrawRect(new SKRect(0, 0, width, (paint.TextSize * 2) + 30), paint);

                        paint.Color = SKColors.White;
                        canvas.DrawText(method.ToString(), width / 2, paint.TextSize + 10, paint);
                        canvas.DrawText("(tap to change)", width / 2, (paint.TextSize * 2) + 10, paint);
                    }
            }
        }
Exemple #13
0
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            canvas.Clear(SKColors.White);

            var paint = new SKPaint
            {
                IsStroke    = true,
                StrokeWidth = 3,
                Color       = SampleMedia.Colors.XamarinLightBlue
            };

            using (var stream = new SKManagedStream(SampleMedia.Images.BabyTux))
                using (var bigBitmap = SKBitmap.Decode(stream))
                {
                    canvas.DrawBitmap(bigBitmap, 10, 10);
                }

            using (var stream = new SKManagedStream(SampleMedia.Images.BabyTux))
                using (var codec = SKCodec.Create(stream))
                {
                    var info    = codec.Info;
                    var subset  = SKRectI.Create(100, 50, 190, 170);
                    var options = new SKCodecOptions(subset);
                    using (var bitmap = new SKBitmap(subset.Width, subset.Height, info.ColorType, SKAlphaType.Premul))
                    {
                        var result = codec.GetPixels(bitmap.Info, bitmap.GetPixels(), options);
                        if (result == SKCodecResult.Success || result == SKCodecResult.IncompleteInput)
                        {
                            canvas.DrawBitmap(bitmap, info.Width + 20, subset.Top + 10);
                        }
                    }
                }
        }
Exemple #14
0
        public void QuickRejectIsCorrect()
        {
            using var region = new SKRegion(SKRectI.Create(10, 10, 100, 100));

            Assert.False(region.QuickReject(SKRectI.Create(50, 50, 100, 100)));
            Assert.False(region.QuickReject(SKRectI.Create(20, 20, 50, 50)));
            Assert.True(region.QuickReject(SKRectI.Create(200, 20, 50, 50)));
        }
Exemple #15
0
        public void RectRegionIsRect()
        {
            using var region = new SKRegion(SKRectI.Create(10, 10, 100, 100));

            Assert.False(region.IsEmpty);
            Assert.True(region.IsRect);
            Assert.False(region.IsComplex);
        }
Exemple #16
0
        public void GetBoundaryPathReturnsNotNullPath()
        {
            using var region = new SKRegion(SKRectI.Create(10, 10, 100, 100));
            region.Op(SKRectI.Create(50, 50, 100, 100), SKRegionOperation.Union);

            using var path = region.GetBoundaryPath();

            Assert.NotNull(path);
        }
Exemple #17
0
        public void TwoRectRegionIsComplex()
        {
            using var region = new SKRegion(SKRectI.Create(10, 10, 100, 100));
            region.Op(SKRectI.Create(50, 50, 100, 100), SKRegionOperation.Union);

            Assert.False(region.IsEmpty);
            Assert.False(region.IsRect);
            Assert.True(region.IsComplex);
        }
Exemple #18
0
        private SpriteComponent CreateTileSprite(Node parent, InitialNodeTransform transform)
        {
            var sprite = parent
                         .CreateChild(transform)
                         .AddComponent(
                new SpriteComponent(TilesetImage, new SpriteData(SKRectI.Create(0, 0, 8, 8)))
                )
                         .AddToCamera(_camera1)
                         .AddToCamera(_camera2);

            return(sprite);
        }
        // Convert tile images to average color
        public void ProcessTileColors(List <byte[]> tileImages)
        {
            foreach (var bytes in tileImages)
            {
                var bitmap = SKBitmap.Decode(bytes);

                if (bitmap != null)
                {
                    var rect = SKRectI.Create(0, 0, bitmap.Width, bitmap.Height);
                    tileImageRGBGridList.Add((bitmap, GetAverageColorGrid(bitmap, rect)));
                }
            }
        }
        public override void Use(Layer activeLayer, Layer previewLayer, IEnumerable <Layer> allLayers, IReadOnlyList <Coordinates> recordedMouseMovement, SKColor color)
        {
            int     thickness = Toolbar.GetSetting <SizeSetting>("ToolSize").Value;
            SKColor?fillColor = null;

            if (Toolbar.GetSetting <BoolSetting>("Fill").Value)
            {
                var temp = Toolbar.GetSetting <ColorSetting>("FillColor").Value;
                fillColor = new SKColor(temp.R, temp.G, temp.B, temp.A);
            }
            var dirtyRect = CreateRectangle(previewLayer, color, fillColor, recordedMouseMovement, thickness);

            ReportCustomSessionRect(SKRectI.Create(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height));
        }
Exemple #21
0
        public Task <byte[]> CropProportionally(byte[] imageData, RectangleF proportionalCropRect)
        {
            using (var skBitmap = SKBitmap.Decode(imageData))
            {
                var absRect = proportionalCropRect.GetAbsoluteRectangle(new Size(skBitmap.Width, skBitmap.Height));

                var image  = SKImage.FromBitmap(skBitmap);
                var subset = image.Subset(SKRectI.Create((int)absRect.X, (int)absRect.Y, (int)absRect.Width, (int)absRect.Height));
                // encode the image
                var encodedData = subset.Encode(SKEncodedImageFormat.Jpeg, 100);

                return(Task.FromResult(encodedData.ToArray()));
            }
        }
Exemple #22
0
 F9PImageData(SKBitmap skBitamp, string key)
 {
     RangeLists = skBitamp.PatchRanges();
     if (RangeLists?.PatchesX != null && RangeLists.PatchesX.Count > 0 && RangeLists.PatchesY != null && RangeLists.PatchesY.Count > 0)
     {
         SKBitmap unmarkedBitmap = new SKBitmap(skBitamp.Width - 1, skBitamp.Height - 1, SKColorType.Rgba8888, SKAlphaType.Unpremul);
         skBitamp.ExtractSubset(unmarkedBitmap, SKRectI.Create(1, 1, skBitamp.Width - 2, skBitamp.Height - 2));
         skBitamp.Dispose();
         skBitamp = unmarkedBitmap.Copy();
     }
     _width   = skBitamp.Width;
     _height  = skBitamp.Height;
     SKBitmap = skBitamp;
     Key      = key;
 }
Exemple #23
0
        public static SKBitmap SquareFromTop(SKBitmap inImg)
        {
            int w           = inImg.Width;
            int h           = inImg.Height;
            int shortestLen = ((w < h) ? w : h);

            /*
             * SKImage image = SKImage.FromBitmap(inImg);
             * SKImage subset = image.Subset(SKRectI.Create(0, yOffset, shortestLen, shortestLen));
             * return subset;*/
            SKRectI  square   = SKRectI.Create(0, h - shortestLen, shortestLen, shortestLen);
            SKBitmap finalBmp = new SKBitmap(shortestLen, shortestLen);

            Debug.WriteLine("DHB:GlobalSingletonHelpers:rotateAndCrop pre extract");
            inImg.ExtractSubset(finalBmp, square);
            return(finalBmp);
        }
Exemple #24
0
        private SKBitmap BuildThumbCollageBitmap(string[] paths, int width, int height)
        {
            var bitmap = new SKBitmap(width, height);

            using (var canvas = new SKCanvas(bitmap))
            {
                canvas.Clear(SKColors.Black);

                // number of images used in the thumbnail
                var iCount = 3;

                // determine sizes for each image that will composited into the final image
                var iSlice     = Convert.ToInt32(width / iCount);
                int iHeight    = Convert.ToInt32(height * 1.00);
                int imageIndex = 0;
                for (int i = 0; i < iCount; i++)
                {
                    using (var currentBitmap = GetNextValidImage(paths, imageIndex, out int newIndex))
                    {
                        imageIndex = newIndex;
                        if (currentBitmap == null)
                        {
                            continue;
                        }

                        // resize to the same aspect as the original
                        int iWidth = Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height);
                        using (var resizeBitmap = new SKBitmap(iWidth, iHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
                        {
                            currentBitmap.ScalePixels(resizeBitmap, SKFilterQuality.High);

                            // crop image
                            int ix = Math.Abs((iWidth - iSlice) / 2);
                            using (var image = SKImage.FromBitmap(resizeBitmap))
                                using (var subset = image.Subset(SKRectI.Create(ix, 0, iSlice, iHeight)))
                                {
                                    // draw image onto canvas
                                    canvas.DrawImage(subset ?? image, iSlice * i, 0);
                                }
                        }
                    }
                }
            }

            return(bitmap);
        }
Exemple #25
0
        [Arguments("t.jpg", "t2.jpg")] // SkiaSharp doesn't have TIFF support
        public void SkiaSharp(string input, string output)
        {
            using (var bitmap = SKBitmap.Decode(input))
            {
                bitmap.ExtractSubset(bitmap, SKRectI.Create(100, 100, bitmap.Width - 200, bitmap.Height - 200));

                var targetWidth  = (int)Math.Round(bitmap.Width * .9F);
                var targetHeight = (int)Math.Round(bitmap.Height * .9F);

                // bitmap.Resize(new SKImageInfo(targetWidth, targetHeight), SKBitmapResizeMethod.Triangle)
                // is deprecated, so we use `SKFilterQuality.Low` instead, see:
                // https://github.com/mono/SkiaSharp/blob/1527bf392ebc7b4b57c992ef8bfe14c9899f76a3/binding/Binding/SKBitmap.cs#L24
                using (var resized = bitmap.Resize(new SKImageInfo(targetWidth, targetHeight), SKFilterQuality.Low))
                {
                    using (var surface = SKSurface.Create(new SKImageInfo(targetWidth, targetHeight, bitmap.ColorType,
                                                                          bitmap.AlphaType)))
                        using (var canvas = surface.Canvas)
                            using (var paint = new SKPaint {
                                FilterQuality = SKFilterQuality.High
                            })
                            {
                                var kernel = new[]
                                {
                                    -1f, -1f, -1f,
                                    -1f, 16f, -1f,
                                    -1f, -1f, -1f
                                };
                                var kernelSize   = new SKSizeI(3, 3);
                                var kernelOffset = new SKPointI(1, 1);

                                paint.ImageFilter = SKImageFilter.CreateMatrixConvolution(kernelSize, kernel, 0.125f, 0f,
                                                                                          kernelOffset, SKMatrixConvolutionTileMode.Repeat, false);

                                canvas.DrawBitmap(resized, 0, 0, paint);
                                canvas.Flush();

                                using (var fileStream = File.OpenWrite(output))
                                {
                                    surface.Snapshot()
                                    .Encode(SKEncodedImageFormat.Jpeg, Quality)
                                    .SaveTo(fileStream);
                                }
                            }
                }
            }
        }
Exemple #26
0
        private SKImage GenerateHomographyMask(FixedCameraEnhancedData configuration, int sourceWidth, int sourceHeight)
        {
            var polygons = GetPolygons(configuration, sourceWidth, sourceHeight);

            using (var tempSurface = SKSurface.Create(new SKImageInfo(sourceWidth, sourceHeight)))
            {
                //get the drawing canvas of the surface
                var canvas = tempSurface.Canvas;

                canvas.Clear(SKColors.Black);

                var fillPaint = new SKPaint
                {
                    Style     = SKPaintStyle.Fill,
                    Color     = SKColors.Transparent,
                    BlendMode = SKBlendMode.Clear
                };

                using (fillPaint)
                {
                    var path = new SKPath();
                    foreach (var points in polygons)
                    {
                        path.MoveTo(points.First());
                        for (var i = 1; i < points.Length; i++)
                        {
                            path.LineTo(points[i]);
                        }
                    }

                    canvas.DrawPath(path, fillPaint);
                }

                using (var image = tempSurface.Snapshot())
                {
                    _croppedSize = new Size(_maxX.Value - _minX.Value, _maxY.Value - _minY.Value);

                    var croppingRectI = SKRectI.Create(_minX.Value, _minY.Value, _croppedSize.Width, _croppedSize.Height);

                    var mask = image.Subset(croppingRectI);

                    return(mask);
                }
            }
        }
        protected byte[] CropImage(byte[] data, int left, int top, int width, int height, int imageQuality)
        {
            (int actualWidth, int actualHeight) = GetImageSize(data);
            width  = width > actualWidth ? actualWidth : width;
            height = height > actualHeight ? actualHeight : height;
            top    = top >= 0 ? top : 0;
            top    = top < actualHeight ? top : 0;
            left   = left >= 0 ? left : 0;
            left   = left < actualWidth ? left : 0;

            using var bitmap       = SKBitmap.Decode(data);
            using var img          = SKImage.FromBitmap(bitmap);
            using var cropped      = img.Subset(SKRectI.Create(left, top, width, height));
            using var jpeg         = cropped.Encode(SKEncodedImageFormat.Jpeg, imageQuality);
            using var memoryStream = new MemoryStream();
            jpeg.AsStream().CopyTo(memoryStream);
            return(memoryStream.ToArray());
        }
        private static (ProcessState state, SKImage image) ReadFullImage(T.Tiff tiff, ImageRequest request, bool allowSizeAboveFull)
        {
            int width  = tiff.GetField(T.TiffTag.IMAGEWIDTH)[0].ToInt();
            int height = tiff.GetField(T.TiffTag.IMAGELENGTH)[0].ToInt();

            var restag  = tiff.GetField(T.TiffTag.RESOLUTIONUNIT);
            var xrestag = tiff.GetField(T.TiffTag.XRESOLUTION);
            var yrestag = tiff.GetField(T.TiffTag.YRESOLUTION);

            var resunit = restag == null ? 2 : restag[0].ToShort();
            var xres    = xrestag == null ? 96 : xrestag[0].ToDouble();
            var yres    = yrestag == null ? 96 : yrestag[0].ToDouble();

            // pixels per metre
            if (resunit == 3)
            {
                xres = xres / 0.0254;
                yres = yres / 0.0254;
            }

            var isTileable = tiff.IsTiled();
            var state      = ImageRequestInterpreter.GetInterpretedValues(request, width, height, allowSizeAboveFull);

            state.HorizontalResolution = Convert.ToUInt16(xres);
            state.VerticalResolution   = Convert.ToUInt16(yres);
            var raster = new int[width * height];

            if (!tiff.ReadRGBAImageOriented(width, height, raster, T.Orientation.TOPLEFT))
            {
                throw new IOException("Unable to decode TIFF file");
            }
            using (var bmp = CreateBitmapFromPixels(raster, width, height))
            {
                var desiredWidth  = Math.Max(1, (int)Math.Round(state.RegionWidth * state.ImageScale));
                var desiredHeight = Math.Max(1, (int)Math.Round(state.RegionHeight * state.ImageScale));
                Log.Debug("Desired size {@DesiredWidth}, {@DesiredHeight}", desiredWidth, desiredHeight);

                var regionWidth  = state.RegionWidth;
                var regionHeight = state.RegionHeight;

                var srcRegion = SKRectI.Create(state.StartX, state.StartY, regionWidth, regionHeight);
                return(state, CopyImageRegion2(bmp, desiredWidth, desiredHeight, srcRegion));
            }
        }
        private static List <SKImage> SplitImageBySeparators(SKImage image, IReadOnlyList <int> separators)
        {
            var subsets = new List <SKImage>();

            for (var i = 0; i < separators.Count - 1; i++)
            {
                var left   = separators[i];
                var right  = separators[i + 1];
                var width  = right - left;
                var height = image.Height;

                var crop = SKRectI.Create(width, height);
                crop.Left  = left;
                crop.Right = right;

                subsets.Add(image.Subset(crop));
            }

            return(subsets);
        }
        public static void sliceTiles(FileStream image, Tuple <double, double> topLeft, Tuple <double, double> bottomRight, string writePath)
        {
            const int tileLength         = 256;
            const int bottomLevel        = 3;
            int       tilesPerDim        = Convert.ToInt32(Math.Pow(2, Convert.ToDouble(bottomLevel)));
            int       pixelsPerDim       = tilesPerDim * tileLength;
            double    degreesLatPerPixel = 180d / pixelsPerDim;
            double    degreesLonPerPixel = degreesLatPerPixel * 2;


            Tuple <int, int> imageTopLeft     = new Tuple <int, int>(Convert.ToInt32((90 - topLeft.Item1) / degreesLatPerPixel), Convert.ToInt32((180 + topLeft.Item2) / degreesLonPerPixel));
            Tuple <int, int> imageBottomRight = new Tuple <int, int>(Convert.ToInt32((90 - bottomRight.Item1) / degreesLatPerPixel), Convert.ToInt32((180 + bottomRight.Item2) / degreesLonPerPixel));

            SKImage sKImage     = SKImage.FromEncodedData(image);
            var     fullSurface = SKSurface.Create(new SKImageInfo(pixelsPerDim, pixelsPerDim));
            var     canvas      = fullSurface.Canvas;

            SKBitmap scaledImage = new SKBitmap(imageBottomRight.Item2 - imageTopLeft.Item2, imageBottomRight.Item1 - imageTopLeft.Item1);

            SKBitmap.FromImage(sKImage).ScalePixels(scaledImage, SKFilterQuality.High);
            canvas.DrawBitmap(scaledImage, new SKPoint(imageTopLeft.Item2, imageTopLeft.Item1));

            SKImage fullImage   = fullSurface.Snapshot();
            var     tileSurface = SKSurface.Create(new SKImageInfo(tileLength, tileLength));

            canvas = tileSurface.Canvas;
            for (int y = 0; y < fullImage.Height; y += tileLength)
            {
                for (int x = 0; x < fullImage.Width; x += tileLength)
                {
                    SKBitmap tile = SKBitmap.FromImage(fullImage.Subset(SKRectI.Create(x, y, tileLength, tileLength)));
                    canvas.Clear(SKColors.Transparent);
                    canvas.DrawBitmap(tile, SKRect.Create(0, 0, tileLength, tileLength));

                    var stream = File.OpenWrite($"{writePath}/aqlatestL{bottomLevel}T{(x / tileLength).ToString("D2")}{(y / tileLength).ToString("D2")}.png");

                    var data = tileSurface.Snapshot().Encode();
                    data.SaveTo(stream);
                }
            }
        }