Esempio n. 1
0
        public static BitmapInfo LoadBitmap(object bitmapStream)
        {
            // todo: Our BitmapRegistry stores not only bitmaps. Perhaps we should store a class in it
            // which has all information. So we should have a SymbolImageRegistry in which we store a
            // SymbolImage. Which holds the type, data and other parameters.
            if (bitmapStream is Stream stream)
            {
                if (stream.IsSvg())
                {
                    var svg = new SKSvg();
                    svg.Load(stream);

                    return(new BitmapInfo {
                        Svg = svg
                    });
                }

                var image = SKImage.FromEncodedData(SKData.CreateCopy(stream.ToBytes()));
                return(new BitmapInfo {
                    Bitmap = image
                });
            }

            if (bitmapStream is Sprite sprite)
            {
                return(new BitmapInfo {
                    Sprite = sprite
                });
            }

            return(null);
        }
Esempio n. 2
0
        public static BitmapInfo LoadBitmap(object bitmapStream)
        {
            if (bitmapStream is Stream stream)
            {
                byte[] buffer = new byte[4];

                stream.Position = 0;
                stream.Read(buffer, 0, 4);
                stream.Position = 0;

                if (System.Text.Encoding.UTF8.GetString(buffer, 0, 4).ToLower().Equals("<svg"))
                {
                    var svg = new SkiaSharp.Extended.Svg.SKSvg();
                    svg.Load(stream);

                    return(new BitmapInfo {
                        Svg = svg
                    });
                }

                var image = SKImage.FromEncodedData(SKData.CreateCopy(stream.ToBytes()));
                return(new BitmapInfo {
                    Bitmap = image
                });
            }

            if (bitmapStream is Sprite sprite)
            {
                return(new BitmapInfo {
                    Sprite = sprite
                });
            }

            return(null);
        }
Esempio n. 3
0
        public void ValidDataProperties()
        {
            var data = SKData.CreateCopy(OddData);

            Assert.Equal(OddData.Length, data.Size);
            Assert.Equal(OddData, data.ToArray());
        }
Esempio n. 4
0
            protected override SKData OnEncode(SKPixmap pixmap)
            {
                DidEncode++;

                EncodedInfo = pixmap.Info;

                return(SKData.CreateCopy(pixmap.GetPixels(), (ulong)pixmap.Info.BytesSize));
            }
Esempio n. 5
0
 private SKImage GetBitmap(byte[] Pixels)
 {
     using (SKData Data = SKData.CreateCopy(Pixels))
     {
         SKImageInfo ImageInfo = new SKImageInfo(this.width, this.height, SKColorType.Rgba8888, SKAlphaType.Premul);
         return(SKImage.FromPixelData(ImageInfo, Data, this.width << 2));
     }
 }
Esempio n. 6
0
        private static readonly SKPaint Paint = new SKPaint(); // Reuse for performance. Only for opacity

        public static BitmapInfo LoadBitmap(Stream bitmapStream)
        {
            bitmapStream.Position = 0;
            var image = SKImage.FromEncodedData(SKData.CreateCopy(bitmapStream.ToBytes()));

            return(new BitmapInfo {
                Bitmap = image
            });
        }
Esempio n. 7
0
 private void initFonts()
 {
     fonts.forEach(s =>
     {
         var buf  = App.LoadData($"fonts/{s}");
         var data = SKData.CreateCopy(buf);
         faces[s] = SKTypeface.FromData(data);
         data.Dispose();
     });
 }
Esempio n. 8
0
        public void CanReadData()
        {
            var bytes = File.ReadAllBytes(Path.Combine(PathToFonts, "Distortable.ttf"));

            using (var data = SKData.CreateCopy(bytes))
                using (var typeface = SKTypeface.FromData(data))
                {
                    Assert.NotNull(typeface);
                }
        }
Esempio n. 9
0
        public void CanReadData()
        {
            var fonts = SKFontManager.Default;

            var bytes = File.ReadAllBytes(Path.Combine(PathToFonts, "Distortable.ttf"));

            using (var data = SKData.CreateCopy(bytes))
                using (var typeface = fonts.CreateTypeface(data))
                {
                    Assert.NotNull(typeface);
                }
        }
Esempio n. 10
0
        /// <summary>
        /// Encodes an image for storage.
        /// </summary>
        /// <param name="imageStream">The image to encode.</param>
        /// <returns>The encoded image, or null if decoding fails.</returns>
        /// <remarks>
        /// The image returned is guaranteed to have no side longer than
        /// <see cref="F:HospitalAllocation.Providers.Image.Database.DbImageProvider.MaxSideLength"/> pixels.
        /// </remarks>
        private static SKData EncodeImage(IImageStream imageStream)
        {
            // Get the image
            var imageArray = new byte[imageStream.Length];
            var stream     = new MemoryStream(imageArray);

            imageStream.CopyTo(stream);

            var data  = SKData.CreateCopy(imageArray);
            var image = SKImage.FromEncodedData(data);

            // Decode failed
            if (image == null)
            {
                return(null);
            }

            // Resize the image if required
            if (Math.Max(image.Height, image.Width) > MaxSideLength)
            {
                int   resizedHeight;
                int   resizedWidth;
                float scale;
                if (image.Height > image.Width)
                {
                    resizedHeight = MaxSideLength;
                    scale         = ((float)resizedHeight / image.Height);
                    resizedWidth  = (int)Math.Round(image.Width * scale);
                }
                else
                {
                    resizedWidth  = MaxSideLength;
                    scale         = ((float)resizedWidth / image.Width);
                    resizedHeight = (int)Math.Round(image.Height * scale);
                }

                var surface = SKSurface.Create(new SKImageInfo(resizedWidth, resizedHeight));
                var paint   = new SKPaint
                {
                    FilterQuality = SKFilterQuality.High
                };
                surface.Canvas.Scale(scale);
                surface.Canvas.DrawImage(image, 0, 0, paint);
                surface.Canvas.Flush();

                image = surface.Snapshot();
            }

            // Encode the image
            return(image.Encode(SKEncodedImageFormat.Jpeg, JpegQualityLevel));
        }
Esempio n. 11
0
        };                                                                                                    // Only for high/med/low quality resizing of tiles

        public static BitmapInfo LoadBitmap(Stream bitmapStream, bool isSvg = false)
        {
            bitmapStream.Position = 0;
            if (isSvg)
            {
                var svg = new SkiaSharp.Extended.Svg.SKSvg();
                svg.Load(bitmapStream);

                return(new BitmapInfo {
                    Svg = svg
                });
            }

            var image = SKImage.FromEncodedData(SKData.CreateCopy(bitmapStream.ToBytes()));

            return(new BitmapInfo {
                Bitmap = image
            });
        }
Esempio n. 12
0
        public void DataDisposedReturnsInvalidStream()
        {
            // create data
            var data = SKData.CreateCopy(OddData);

            // get the stream
            var stream = data.AsStream();

            // nuke the data
            data.Dispose();
            Assert.Equal(IntPtr.Zero, data.Handle);

            // read the stream
            var buffer = new byte[OddData.Length];

            stream.Read(buffer, 0, buffer.Length);

            // since the data was nuked, they will differ
            Assert.NotEqual(OddData, buffer);
        }
Esempio n. 13
0
        public static BitmapInfo LoadBitmap(object bitmapStream)
        {
            // todo: Our BitmapRegistry stores not only bitmaps. Perhaps we should store a class in it
            // which has all information. So we should have a SymbolImageRegistry in which we store a
            // SymbolImage. Which holds the type, data and other parameters.
            if (bitmapStream is Stream stream)
            {
                byte[] buffer = new byte[4];

                stream.Position = 0;
                stream.Read(buffer, 0, 4);
                stream.Position = 0;

                if (System.Text.Encoding.UTF8.GetString(buffer, 0, 4).ToLower().Equals("<svg"))
                {
                    var svg = new SkiaSharp.Extended.Svg.SKSvg();
                    svg.Load(stream);

                    return(new BitmapInfo {
                        Svg = svg
                    });
                }

                var image = SKImage.FromEncodedData(SKData.CreateCopy(stream.ToBytes()));
                return(new BitmapInfo {
                    Bitmap = image
                });
            }

            if (bitmapStream is Sprite sprite)
            {
                return(new BitmapInfo {
                    Sprite = sprite
                });
            }

            return(null);
        }
Esempio n. 14
0
 public Bitmap(byte[] largeIconsImage, Size clientSizeHeight)
 {
     nativeSkBitmap = SKBitmap.Decode(SKData.CreateCopy(largeIconsImage)).Resize(
         new SKImageInfo(clientSizeHeight.Width, clientSizeHeight.Height),
         SKFilterQuality.High);
 }
Esempio n. 15
0
        private SKData GetImageData(string imagePath, ResizeParams resizeParams, DateTime lastWriteTimeUtc)
        {
            // check cache and return if cached
            long cacheKey;

            unchecked
            {
                cacheKey = imagePath.GetHashCode() + lastWriteTimeUtc.ToBinary() + resizeParams.ToString().GetHashCode();
            }

            SKData imageData;

            byte[] imageBytes;
            bool   isCached = _memoryCache.TryGetValue <byte[]>(cacheKey, out imageBytes);

            if (isCached)
            {
                _logger.LogInformation("Serving from cache");
                return(SKData.CreateCopy(imageBytes));
            }

            SKCodecOrigin origin;                                                    // this represents the EXIF orientation
            var           bitmap = LoadBitmap(File.OpenRead(imagePath), out origin); // always load as 32bit (to overcome issues with indexed color)

            // if autorotate = true, and origin isn't correct for the rotation, rotate it
            if (resizeParams.autorotate && origin != SKCodecOrigin.TopLeft)
            {
                bitmap = RotateAndFlip(bitmap, origin);
            }

            // if either w or h is 0, set it based on ratio of original image
            if (resizeParams.h == 0)
            {
                resizeParams.h = (int)Math.Round(bitmap.Height * (float)resizeParams.w / bitmap.Width);
            }
            else if (resizeParams.w == 0)
            {
                resizeParams.w = (int)Math.Round(bitmap.Width * (float)resizeParams.h / bitmap.Height);
            }

            // if we need to crop, crop the original before resizing
            if (resizeParams.mode == "crop")
            {
                bitmap = Crop(bitmap, resizeParams);
            }

            // store padded height and width
            var paddedHeight = resizeParams.h;
            var paddedWidth  = resizeParams.w;

            // if we need to pad, or max, set the height or width according to ratio
            if (resizeParams.mode == "pad" || resizeParams.mode == "max")
            {
                var bitmapRatio = (float)bitmap.Width / bitmap.Height;
                var resizeRatio = (float)resizeParams.w / resizeParams.h;

                if (bitmapRatio > resizeRatio) // original is more "landscape"
                {
                    resizeParams.h = (int)Math.Round(bitmap.Height * ((float)resizeParams.w / bitmap.Width));
                }
                else
                {
                    resizeParams.w = (int)Math.Round(bitmap.Width * ((float)resizeParams.h / bitmap.Height));
                }
            }

            // resize
            var resizedImageInfo = new SKImageInfo(resizeParams.w, resizeParams.h, SKImageInfo.PlatformColorType, bitmap.AlphaType);
            var resizedBitmap    = bitmap.Resize(resizedImageInfo, SKBitmapResizeMethod.Lanczos3);

            // optionally pad
            if (resizeParams.mode == "pad")
            {
                resizedBitmap = Pad(resizedBitmap, paddedWidth, paddedHeight, resizeParams.format != "png");
            }

            // encode
            var resizedImage = SKImage.FromBitmap(resizedBitmap);
            var encodeFormat = resizeParams.format == "png" ? SKEncodedImageFormat.Png : SKEncodedImageFormat.Jpeg;

            imageData = resizedImage.Encode(encodeFormat, resizeParams.quality);

            // cache the result
            _memoryCache.Set <byte[]>(cacheKey, imageData.ToArray());

            // cleanup
            resizedImage.Dispose();
            bitmap.Dispose();
            resizedBitmap.Dispose();

            return(imageData);
        }
Esempio n. 16
0
        private SKData GetImageData(string imagePath, ResizeParams resizeParams, DateTime lastWriteTimeUtc)
        {
            // check cache and return if cached
            string cacheKey;

            unchecked
            {
                cacheKey = "imgasc_" + imagePath.GetHashCode() + lastWriteTimeUtc.ToBinary() + resizeParams.ToString().GetHashCode();
            }

            SKData imageData;

            byte[] cacheData = _asyncCacheService.GetByKeyAsync <byte[]>(cacheKey).Result;
            if (cacheData != null)
            {
                return(SKData.CreateCopy(cacheData));
            }

            // this represents the EXIF orientation
            SKBitmap bitmap = LoadBitmap(File.OpenRead(imagePath), out SKEncodedOrigin origin); // always load as 32bit (to overcome issues with indexed color)

            // if autorotate = true, and origin isn't correct for the rotation, rotate it
            if (resizeParams.autorotate && origin != SKEncodedOrigin.TopLeft)
            {
                bitmap = RotateAndFlip(bitmap, origin);
            }

            // if either w or h is 0, set it based on ratio of original image
            if (resizeParams.h == 0)
            {
                resizeParams.h = (int)Math.Round(bitmap.Height * (float)resizeParams.w / bitmap.Width);
            }
            else if (resizeParams.w == 0)
            {
                resizeParams.w = (int)Math.Round(bitmap.Width * (float)resizeParams.h / bitmap.Height);
            }

            // if we need to crop, crop the original before resizing
            if (resizeParams.mode == "crop")
            {
                bitmap = Crop(bitmap, resizeParams);
            }

            // store padded height and width
            int paddedHeight = resizeParams.h;
            int paddedWidth  = resizeParams.w;

            // if we need to pad, or max, set the height or width according to ratio
            if (resizeParams.mode == "pad" || resizeParams.mode == "max")
            {
                float bitmapRatio = (float)bitmap.Width / bitmap.Height;
                float resizeRatio = (float)resizeParams.w / resizeParams.h;

                if (bitmapRatio > resizeRatio) // original is more "landscape"
                {
                    resizeParams.h = (int)Math.Round(bitmap.Height * ((float)resizeParams.w / bitmap.Width));
                }
                else
                {
                    resizeParams.w = (int)Math.Round(bitmap.Width * ((float)resizeParams.h / bitmap.Height));
                }
            }

            // resize
            SKImageInfo resizedImageInfo = new SKImageInfo(resizeParams.w, resizeParams.h, SKImageInfo.PlatformColorType, bitmap.AlphaType);
            SKBitmap    resizedBitmap    = bitmap.Resize(resizedImageInfo, SKFilterQuality.None);

            // optionally pad
            if (resizeParams.mode == "pad")
            {
                resizedBitmap = Pad(resizedBitmap, paddedWidth, paddedHeight, resizeParams.format != "png");
            }

            // encode
            SKImage resizedImage = SKImage.FromBitmap(resizedBitmap);
            SKEncodedImageFormat encodeFormat = resizeParams.format == "png" ? SKEncodedImageFormat.Png : SKEncodedImageFormat.Jpeg;

            imageData = resizedImage.Encode(encodeFormat, resizeParams.quality);

            // cache the result
            _asyncCacheService.SetValueAsync(cacheKey, imageData.ToArray());

            // cleanup
            resizedImage.Dispose();
            bitmap.Dispose();
            resizedBitmap.Dispose();

            return(imageData);
        }
Esempio n. 17
0
 public static SKData ToSKData(this NSData nsData)
 {
     return(SKData.CreateCopy(nsData.Bytes, nsData.Length));
 }
Esempio n. 18
0
        public static BitmapInfo?LoadBitmap(object?bitmapStream)
        {
            // todo: Our BitmapRegistry stores not only bitmaps. Perhaps we should store a class in it
            // which has all information. So we should have a SymbolImageRegistry in which we store a
            // SymbolImage. Which holds the type, data and other parameters.

            if (bitmapStream is SKImage skBitmap)
            {
                return(new BitmapInfo {
                    Bitmap = skBitmap,
                });
            }

            if (bitmapStream is SKPicture skPicture)
            {
                return(new BitmapInfo {
                    Picture = skPicture
                });
            }

            if (bitmapStream is string str)
            {
                if (str.ToLower().Contains("<svg"))
                {
                    return(new BitmapInfo {
                        Svg = str.LoadSvg()
                    });
                }
            }

            if (bitmapStream is byte[] data)
            {
                if (data.IsXml())
                {
                    using var tempStream = new MemoryStream(data);
                    if (tempStream.IsSvg())
                    {
                        return(new BitmapInfo {
                            Svg = tempStream.LoadSvg()
                        });
                    }
                }

                using var skData = SKData.CreateCopy(data);
                var image = SKImage.FromEncodedData(skData);
                return(new BitmapInfo {
                    Bitmap = image
                });
            }

            if (bitmapStream is Stream stream)
            {
                if (stream.IsSvg())
                {
                    return(new BitmapInfo {
                        Svg = stream.LoadSvg()
                    });
                }

                using var skData = SKData.CreateCopy(stream.ToBytes());
                var image = SKImage.FromEncodedData(skData);
                return(new BitmapInfo {
                    Bitmap = image
                });
            }

            if (bitmapStream is Sprite sprite)
            {
                return(new BitmapInfo {
                    Sprite = sprite
                });
            }

            return(null);
        }
Esempio n. 19
0
        private static async Task CompareVisualResult(double totalWidth, double totalHeight,
                                                      List <RenderFinishedEventArgs> result, string referenceFileName,
                                                      Uint8Array referenceFileData, string?message)
        {
            // TODO: get Skia to render like Chrome
            // https://github.com/mono/SkiaSharp/issues/1253
            return;

            SKBitmap finalBitmap;

            using (var finalImageSurface = SKSurface.Create(new SKImageInfo((int)totalWidth,
                                                                            (int)totalHeight,
                                                                            SKImageInfo.PlatformColorType, SKAlphaType.Premul)))
            {
                var point     = new SKPoint();
                var rowHeight = 0;
                foreach (var partialResult in result)
                {
                    var partialCanvas = partialResult.RenderResult;
                    if (partialCanvas is SKImage img)
                    {
                        finalImageSurface.Canvas.DrawImage(img, point);
                        if (partialResult.Height > rowHeight)
                        {
                            rowHeight = img.Height;
                        }

                        point.X += img.Width;

                        if (point.X >= totalWidth)
                        {
                            point.X   = 0;
                            point.Y  += rowHeight;
                            rowHeight = 0;
                        }
                    }
                }

                using var finalImage = finalImageSurface.Snapshot();
                finalBitmap          = SKBitmap.FromImage(finalImage);
            }

            var finalImageFileName = Path.ChangeExtension(referenceFileName, ".new.png");

            using (finalBitmap)
            {
                var dir = Path.GetDirectoryName(finalImageFileName);
                Directory.CreateDirectory(dir);

                using (var fileStream = new SKFileWStream(finalImageFileName))
                {
                    SKPixmap.Encode(fileStream, finalBitmap, SKEncodedImageFormat.Png, 100);
                }

                SKBitmap referenceBitmap;
                using (var data = SKData.CreateCopy(referenceFileData.Buffer.Raw))
                {
                    referenceBitmap = SKBitmap.Decode(data);
                }

                using (referenceBitmap)
                {
                    var compareResult = PixelMatch.Run(finalBitmap, referenceBitmap,
                                                       new PixelMatchOptions
                    {
                        Threshold         = 0.8,
                        IncludeAntiAlias  = false,
                        IgnoreTransparent = true,
                        CreateOutputImage = true
                    });


                    using (compareResult.Output)
                    {
                        Assert.IsTrue(compareResult.SizesMatch, "Dimensions differ");
                        if (compareResult.Mismatch > 0.01)
                        {
                            var diffImageName =
                                Path.ChangeExtension(referenceFileName, ".diff.png");
                            using (var fileStream = new SKFileWStream(diffImageName))
                            {
                                SKPixmap.Encode(fileStream, compareResult.Output,
                                                SKEncodedImageFormat.Png, 100);
                            }

                            Assert.Fail(
                                $"Difference between original and new image is too big: {compareResult.Mismatch:P}, {compareResult.DifferentPixels}/{compareResult.TotalPixels}");
                        }
                    }
                }
            }

            File.Delete(finalImageFileName);
        }