예제 #1
0
        public ImageSize GetImageSize(string path)
        {
            using (var s = new SKFileStream(path))
            {
                using (var codec = SKCodec.Create(s))
                {
                    var info = codec.Info;

                    return(new ImageSize
                    {
                        Width = info.Width,
                        Height = info.Height
                    });
                }
            }
        }
예제 #2
0
        /// <inheritdoc />
        /// <exception cref="ArgumentNullException">The path is null.</exception>
        /// <exception cref="FileNotFoundException">The path is not valid.</exception>
        /// <exception cref="SkiaCodecException">The file at the specified path could not be used to generate a codec.</exception>
        public ImageDimensions GetImageSize(string path)
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException("File not found", path);
            }

            using (var codec = SKCodec.Create(path, out SKCodecResult result))
            {
                EnsureSuccess(result);

                var info = codec.Info;

                return(new ImageDimensions(info.Width, info.Height));
            }
        }
        public AnimatedGifPage()
        {
            InitializeComponent();

            string   resourceID = "SkiaSharpFormsDemos.Media.Newtons_cradle_animation_book_2.gif";
            Assembly assembly   = GetType().GetTypeInfo().Assembly;

            using (Stream stream = assembly.GetManifestResourceStream(resourceID))
                using (SKManagedStream skStream = new SKManagedStream(stream))
                    using (SKCodec codec = SKCodec.Create(skStream))
                    {
                        // Get frame count and allocate bitmaps
                        int frameCount = codec.FrameCount;
                        bitmaps              = new SKBitmap[frameCount];
                        durations            = new int[frameCount];
                        accumulatedDurations = new int[frameCount];
                        // Note: There's also a RepetitionCount property of SKCodec not used here
                        // Loop through the frames
                        for (int frame = 0; frame < frameCount; frame++)
                        {
                            // From the FrameInfo collection, get the duration of each frame
                            durations[frame] = codec.FrameInfo[frame].Duration;
                            // Create a full-color bitmap for each frame
                            SKImageInfo imageInfo = new SKImageInfo(codec.Info.Width, codec.Info.Height);
                            bitmaps[frame] = new SKBitmap(imageInfo);
                            // Get the address of the pixels in that bitmap
                            IntPtr pointer = bitmaps[frame].GetPixels();
                            // Create an SKCodecOptions value to specify the frame
                            SKCodecOptions codecOptions = new SKCodecOptions(frame, false);
                            // Copy pixels from the frame into the bitmap
                            codec.GetPixels(imageInfo, pointer, codecOptions);
                        }

                        // Sum up the total duration
                        for (int frame = 0; frame < durations.Length; frame++)
                        {
                            totalDuration += durations[frame];
                        }

                        // Calculate the accumulated durations
                        for (int frame = 0; frame < durations.Length; frame++)
                        {
                            accumulatedDurations[frame] = durations[frame] +
                                                          (frame == 0 ? 0 : accumulatedDurations[frame - 1]);
                        }
                    }
        }
예제 #4
0
        public unsafe void StreamThatHasLostOwnershipIsDisposed()
        {
            var bytes  = File.ReadAllBytes(Path.Combine(PathToImages, "color-wheel.png"));
            var dotnet = new MemoryStream(bytes);
            var stream = new SKManagedStream(dotnet, true);
            var handle = stream.Handle;

            Assert.True(stream.OwnsHandle);
            Assert.True(SKObject.GetInstance <SKManagedStream>(handle, out _));

            var codec = SKCodec.Create(stream);

            Assert.False(stream.OwnsHandle);

            codec.Dispose();
            Assert.False(SKObject.GetInstance <SKManagedStream>(handle, out _));
        }
예제 #5
0
        public void BitmapDecodesCorrectly()
        {
            byte[] codecPixels;
            byte[] bitmapPixels;

            using (var codec = SKCodec.Create(new SKFileStream(Path.Combine(PathToImages, "baboon.png"))))
            {
                codecPixels = codec.Pixels;
            }

            using (var bitmap = SKBitmap.Decode(Path.Combine(PathToImages, "baboon.png")))
            {
                bitmapPixels = bitmap.Bytes;
            }

            Assert.Equal(codecPixels, bitmapPixels);
        }
예제 #6
0
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            canvas.Clear(SKColors.White);

            // load the embedded resource stream
            using (var stream = new SKManagedStream(SampleMedia.Images.ColorWheel))
                using (var codec = SKCodec.Create(stream))
                    using (var paint = new SKPaint())
                        using (var tf = SKTypeface.FromFamilyName("Arial"))
                        {
                            var info        = codec.Info;
                            var encodedInfo = codec.EncodedInfo;

                            paint.IsAntialias = true;
                            paint.TextSize    = 14;
                            paint.Typeface    = tf;
                            paint.Color       = SKColors.Black;

                            // decode the image
                            using (var bitmap = new SKBitmap(info.Width, info.Height, info.ColorType, info.IsOpaque ? SKAlphaType.Opaque : SKAlphaType.Premul))
                            {
                                IntPtr length;
                                var    result = codec.GetPixels(bitmap.Info, bitmap.GetPixels(out length));
                                if (result == SKCodecResult.Success || result == SKCodecResult.IncompleteInput)
                                {
                                    var x = 25;
                                    var y = 25;

                                    canvas.DrawBitmap(bitmap, x, y);
                                    x += bitmap.Info.Width + 25;
                                    y += 14;

                                    canvas.DrawText(string.Format("Result: {0}", result), x, y, paint);
                                    y += 20;

                                    canvas.DrawText(string.Format("Size: {0}px x {1}px", bitmap.Width, bitmap.Height), x, y, paint);
                                    y += 20;

                                    canvas.DrawText(string.Format("Pixels: {0} @ {1}b/px", bitmap.Pixels.Length, bitmap.BytesPerPixel), x, y, paint);
                                    y += 20;

                                    canvas.DrawText(string.Format("Encoding: {0} ({1}) @ {2}-bit color", encodedInfo.Color, encodedInfo.Alpha, encodedInfo.BitsPerComponent), x, y, paint);
                                }
                            }
                        }
        }
예제 #7
0
        public void BitmapDecodesCorrectlyWithManagedStream()
        {
            byte[] codecPixels;
            byte[] bitmapPixels;

            var stream = File.OpenRead(Path.Combine(PathToImages, "baboon.png"));

            using (var codec = SKCodec.Create(new SKManagedStream(stream))) {
                codecPixels = codec.Pixels;
            }

            using (var bitmap = SKBitmap.Decode(Path.Combine(PathToImages, "baboon.png"))) {
                bitmapPixels = bitmap.Bytes;
            }

            Assert.Equal(codecPixels, bitmapPixels);
        }
예제 #8
0
        private SKBitmap GetChildViewImage()
        {
            var     r     = DependencyService.Get <IViewImageProvider>(DependencyFetchTarget.GlobalInstance).GetViewImage(ChildView);
            SKCodec codec = SKCodec.Create(new MemoryStream(r));

            return(SKBitmap.Decode(codec));

            //string resourceID = "FormsRevealer.Sample.ape.jpg";
            //Assembly assembly = GetType().GetTypeInfo().Assembly;

            //SKBitmap resourceBitmap;
            //using (Stream stream = assembly.GetManifestResourceStream(resourceID))
            //{
            //    resourceBitmap = SKBitmap.Decode(stream);
            //}

            //return resourceBitmap;
        }
예제 #9
0
        private SKBitmap LoadBitmap(Stream stream, out SKEncodedOrigin origin)
        {
            using var managedStream = new SKManagedStream(stream);
            using var codec         = SKCodec.Create(managedStream);

            origin = codec.EncodedOrigin;

            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);
            }

            throw new ArgumentException("Невозможно загрузить изображение из источника.");
        }
예제 #10
0
        private static TwitchEmote GetTwitchEmote(string fileName, string url, string name, string imageType, string id, int imageScale)
        {
            try
            {
                using (WebClient client = new WebClient())
                {
                    SKBitmap emoteBitmap = null;
                    byte[]   bytes       = null;
                    bool     fileExists  = File.Exists(fileName);
                    if (fileExists)
                    {
                        //File may already be locked, can just download again from URL
                        try
                        {
                            bytes = File.ReadAllBytes(fileName);
                        }
                        catch { }
                        emoteBitmap = SKBitmap.Decode(bytes);
                    }

                    if (!fileExists || emoteBitmap == null)
                    {
                        bytes = client.DownloadData(url);
                        try
                        {
                            //File may already be open, just a cache so can ignore
                            File.WriteAllBytes(fileName, bytes);
                        }
                        catch { }
                        emoteBitmap = SKBitmap.Decode(bytes);
                    }

                    MemoryStream ms = new MemoryStream(bytes);
                    return(new TwitchEmote(new List <SKBitmap>()
                    {
                        emoteBitmap
                    }, SKCodec.Create(ms), name, imageType, id, imageScale, bytes));
                }
            }
            catch
            {
                return(null);
            }
        }
예제 #11
0
        private void LoadPng(Item item)
        {
            try
            {
                if (!File.Exists(item.ReferencePngPath))
                {
                    return;
                }

                using var codec = SKCodec.Create(new SKFileStream(item.ReferencePngPath));
#if USE_COLORSPACE
                var skImageInfo = new SKImageInfo(codec.Info.Width, codec.Info.Height, SKSvg.s_colorType, SKSvg.s_alphaType, SvgPaintingExtensions.Srgb);
#else
                var skImageInfo = new SKImageInfo(codec.Info.Width, codec.Info.Height, SKSvg.s_colorType, SKSvg.s_alphaType);
#endif
                var skReferenceBitmap = new SKBitmap(skImageInfo);
                codec.GetPixels(skReferenceBitmap.Info, skReferenceBitmap.GetPixels());
                if (skReferenceBitmap == null)
                {
                    return;
                }

                item.ReferencePng = skReferenceBitmap;

                float scaleX = skReferenceBitmap.Width / item.Picture.CullRect.Width;
                float scaleY = skReferenceBitmap.Height / item.Picture.CullRect.Height;
#if USE_COLORSPACE
                using var svgBitmap = item.Picture.ToBitmap(SKColors.Transparent, scaleX, scaleY, SKSvg.s_colorType, SKSvg.s_alphaType, SvgPaintingExtensions.Srgb);
#else
                using var svgBitmap = item.Picture.ToBitmap(SKColors.Transparent, scaleX, scaleY, SKSvg.s_colorType, SKSvg.s_alphaType);
#endif
                if (svgBitmap.Width == skReferenceBitmap.Width && svgBitmap.Height == skReferenceBitmap.Height)
                {
                    var pixelDiff = PixelDiff(skReferenceBitmap, svgBitmap);
                    item.PixelDiff = pixelDiff;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Failed to load reference png: {item.ReferencePngPath}");
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
            }
        }
예제 #12
0
        private SKBitmap LoadBitmap(Stream stream, out SKEncodedOrigin origin)
        {
            using SKManagedStream s = new SKManagedStream(stream);
            using SKCodec codec     = SKCodec.Create(s);
            origin = codec.EncodedOrigin;
            SKImageInfo info   = codec.Info;
            SKBitmap    bitmap = new SKBitmap(info.Width, info.Height, SKImageInfo.PlatformColorType, info.IsOpaque ? SKAlphaType.Opaque : SKAlphaType.Premul);

            SKCodecResult result = codec.GetPixels(bitmap.Info, bitmap.GetPixels(out IntPtr length));

            if (result == SKCodecResult.Success || result == SKCodecResult.IncompleteInput)
            {
                return(bitmap);
            }
            else
            {
                throw new ArgumentException("Unable to load bitmap from provided data");
            }
        }
예제 #13
0
        public unsafe void StreamLosesOwnershipToCodecButIsNotForgotten()
        {
            var bytes  = File.ReadAllBytes(Path.Combine(PathToImages, "color-wheel.png"));
            var stream = new SKMemoryStream(bytes);
            var handle = stream.Handle;

            Assert.True(stream.OwnsHandle);
            Assert.True(SKObject.GetInstance <SKMemoryStream>(handle, out _));

            var codec = SKCodec.Create(stream);

            Assert.False(stream.OwnsHandle);

            stream.Dispose();
            Assert.True(SKObject.GetInstance <SKMemoryStream>(handle, out _));

            Assert.Equal(SKCodecResult.Success, codec.GetPixels(out var pixels));
            Assert.NotEmpty(pixels);
        }
예제 #14
0
        /// <summary>
        /// Encodes the BlurHash representation of the image.
        /// </summary>
        /// <param name="xComponent">The number x components.</param>
        /// <param name="yComponent">The number y components.</param>
        /// <param name="filename">The path to an encoded image on the file system.</param>
        /// <returns>BlurHash representation of the image.</returns>
        public static string Encode(int xComponent, int yComponent, string filename)
        {
            using (SKCodec codec = SKCodec.Create(filename))
            {
                var newInfo = new SKImageInfo()
                {
                    Width      = codec.Info.Width,
                    Height     = codec.Info.Height,
                    ColorType  = SKColorType.Rgba8888,
                    AlphaType  = SKAlphaType.Unpremul,
                    ColorSpace = SKColorSpace.CreateSrgb()
                };

                using (SKBitmap bitmap = SKBitmap.Decode(codec, newInfo))
                {
                    return(EncodeInternal(xComponent, yComponent, bitmap));
                }
            }
        }
예제 #15
0
        public WriteableBitmapImpl(Stream stream, int decodeSize, bool horizontal, BitmapInterpolationMode interpolationMode)
        {
            using (var skStream = new SKManagedStream(stream))
                using (var skData = SKData.Create(skStream))
                    using (var codec = SKCodec.Create(skData))
                    {
                        var info = codec.Info;

                        // get the scale that is nearest to what we want (eg: jpg returned 512)
                        var supportedScale = codec.GetScaledDimensions(horizontal ? ((float)decodeSize / info.Width) : ((float)decodeSize / info.Height));

                        // decode the bitmap at the nearest size
                        var nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height);
                        var bmp     = SKBitmap.Decode(codec, nearest);

                        // now scale that to the size that we want
                        var realScale = horizontal ? ((double)info.Height / info.Width) : ((double)info.Width / info.Height);

                        SKImageInfo desired;


                        if (horizontal)
                        {
                            desired = new SKImageInfo(decodeSize, (int)(realScale * decodeSize));
                        }
                        else
                        {
                            desired = new SKImageInfo((int)(realScale * decodeSize), decodeSize);
                        }

                        if (bmp.Width != desired.Width || bmp.Height != desired.Height)
                        {
                            var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKFilterQuality());
                            bmp.Dispose();
                            bmp = scaledBmp;
                        }

                        _bitmap = bmp;

                        PixelSize = new PixelSize(bmp.Width, bmp.Height);
                        Dpi       = SkiaPlatform.DefaultDpi;
                    }
        }
예제 #16
0
        public void GetGifFrames()
        {
            const int FrameCount = 16;

            var stream = new SKFileStream(Path.Combine(PathToImages, "animated-heart.gif"));

            using (var codec = SKCodec.Create(stream)) {
                Assert.Equal(-1, codec.RepetitionCount);

                var frameInfos = codec.FrameInfo;
                Assert.Equal(FrameCount, frameInfos.Length);

                Assert.Equal(-1, frameInfos [0].RequiredFrame);

                var cachedFrames = new SKBitmap [FrameCount];
                var info         = new SKImageInfo(codec.Info.Width, codec.Info.Height);

                var decode = new Action <SKBitmap, bool, int> ((bm, cached, index) => {
                    if (cached)
                    {
                        var requiredFrame = frameInfos [index].RequiredFrame;
                        if (requiredFrame != -1)
                        {
                            Assert.True(cachedFrames [requiredFrame].CopyTo(bm));
                        }
                    }
                    var opts   = new SKCodecOptions(index, cached);
                    var result = codec.GetPixels(info, bm.GetPixels(), opts);
                    Assert.Equal(SKCodecResult.Success, result);
                });

                for (var i = 0; i < FrameCount; i++)
                {
                    var cachedFrame = cachedFrames [i] = new SKBitmap(info);
                    decode(cachedFrame, true, i);

                    var uncachedFrame = new SKBitmap(info);
                    decode(uncachedFrame, false, i);

                    Assert.Equal(cachedFrame.Bytes, uncachedFrame.Bytes);
                }
            }
        }
예제 #17
0
        public void CanCreateStreamCodec()
        {
            var stream = new SKFileStream(Path.Combine(PathToImages, "color-wheel.png"));

            using (var codec = SKCodec.Create(stream)) {
                Assert.AreEqual(SKEncodedFormat.Png, codec.EncodedFormat);
                Assert.AreEqual(128, codec.Info.Width);
                Assert.AreEqual(128, codec.Info.Height);
                Assert.AreEqual(SKAlphaType.Unpremul, codec.Info.AlphaType);
                if (IsUnix)
                {
                    Assert.AreEqual(SKColorType.Rgba8888, codec.Info.ColorType);
                }
                else
                {
                    Assert.AreEqual(SKColorType.Bgra8888, codec.Info.ColorType);
                }
            }
        }
예제 #18
0
        public IImage LoadImageFromStream(Stream stream, ImageFormat formatHint = ImageFormat.Png)
        {
            using (var s = new SKManagedStream(stream))
            {
                using (var codec = SKCodec.Create(s))
                {
                    var info   = codec.Info;
                    var bitmap = new SKBitmap(info.Width, info.Height, info.ColorType, info.IsOpaque ? SKAlphaType.Opaque : SKAlphaType.Premul);

                    var result = codec.GetPixels(bitmap.Info, bitmap.GetPixels(out _));
                    if (result == SKCodecResult.Success || result == SKCodecResult.IncompleteInput)
                    {
                        return(new SkiaImage(bitmap));
                    }
                }
            }

            return(null);
        }
예제 #19
0
        /// <summary>
        /// Resizes the image and encodes the BlurHash representation of the image.
        /// </summary>
        /// <param name="xComponent">The number x components.</param>
        /// <param name="yComponent">The number y components.</param>
        /// <param name="filename">The path to an encoded image on the file system.</param>
        /// <param name="maxWidth">The maximum width to resize the image to.</param>
        /// <param name="maxHeight">The maximum height to resize the image to.</param>
        /// <returns>BlurHash representation of the image.</returns>
        public static string Encode(int xComponent, int yComponent, string filename, int maxWidth, int maxHeight)
        {
            using (SKCodec codec = SKCodec.Create(filename))
            {
                var   width       = codec.Info.Width;
                var   height      = codec.Info.Height;
                float scaleFactor = 0;
                if (width > maxWidth || height > maxHeight)
                {
                    scaleFactor = ScaleHelper.GetScale(width, height, maxWidth, maxHeight);
                    SKSizeI supportedScale = codec.GetScaledDimensions(scaleFactor);
                    width  = supportedScale.Width;
                    height = supportedScale.Height;
                }

                var newInfo = new SKImageInfo()
                {
                    Width      = width,
                    Height     = height,
                    ColorType  = SKColorType.Rgba8888,
                    AlphaType  = SKAlphaType.Unpremul,
                    ColorSpace = SKColorSpace.CreateSrgb()
                };

                using (SKBitmap bitmap = SKBitmap.Decode(codec, newInfo))
                {
                    if (scaleFactor == 0)
                    {
                        return(EncodeInternal(xComponent, yComponent, bitmap));
                    }

                    var(scaledWidth, scaledHeight) = ScaleHelper.GetScaleDimensions(bitmap.Width, bitmap.Height, scaleFactor);

                    newInfo = newInfo.WithSize(scaledWidth, scaledHeight);

                    using (SKBitmap scaledBitmap = bitmap.Resize(newInfo, SKFilterQuality.Low))
                    {
                        return(EncodeInternal(xComponent, yComponent, scaledBitmap));
                    }
                }
            }
        }
예제 #20
0
        public unsafe void StreamLosesOwnershipAndCanBeGarbageCollected()
        {
            VerifyImmediateFinalizers();

            var bytes = File.ReadAllBytes(Path.Combine(PathToImages, "color-wheel.png"));

            DoWork(out var codecH, out var streamH);

            CollectGarbage();

            Assert.False(SKObject.GetInstance <SKMemoryStream>(streamH, out _));
            Assert.False(SKObject.GetInstance <SKCodec>(codecH, out _));

            void DoWork(out IntPtr codecHandle, out IntPtr streamHandle)
            {
                var codec = CreateCodec(out streamHandle);

                codecHandle = codec.Handle;

                CollectGarbage();

                Assert.Equal(SKCodecResult.Success, codec.GetPixels(out var pixels));
                Assert.NotEmpty(pixels);

                Assert.True(SKObject.GetInstance <SKMemoryStream>(streamHandle, out var stream));
                Assert.False(stream.OwnsHandle);
                Assert.True(stream.IgnorePublicDispose);
            }

            SKCodec CreateCodec(out IntPtr streamHandle)
            {
                var stream = new SKMemoryStream(bytes);

                streamHandle = stream.Handle;

                Assert.True(stream.OwnsHandle);
                Assert.False(stream.IgnorePublicDispose);
                Assert.True(SKObject.GetInstance <SKMemoryStream>(streamHandle, out _));

                return(SKCodec.Create(stream));
            }
        }
예제 #21
0
파일: ImageReader.cs 프로젝트: Zbyszard/NTP
        public async Task Init(Stream sourceStream)
        {
            if (Image != null)
            {
                return;
            }
            FileStream = sourceStream;
            var reading = Task.Run(() =>
            {
                var data   = SKData.Create(sourceStream);
                var image  = SKImage.FromEncodedData(data);
                var bitmap = SKBitmap.FromImage(image);
                var codec  = SKCodec.Create(data);
                SKEncodedImageFormat imgFormat = codec.EncodedFormat;
                SKImageInfo info = codec.Info;
                return(image, bitmap, info, imgFormat);
            });

            (Image, Bitmap, Info, Format) = await reading;
        }
예제 #22
0
        public void EncodeWithSimpleSerializer()
        {
            var bitmap = CreateTestBitmap();

            bool encoded    = false;
            var  serializer = SKPixelSerializer.Create(pixmap =>
            {
                encoded = true;
                return(pixmap.Encode(SKEncodedImageFormat.Jpeg, 100));
            });

            var image = SKImage.FromBitmap(bitmap);
            var data  = image.Encode(serializer);

            var codec = SKCodec.Create(data);

            Assert.Equal(SKEncodedImageFormat.Jpeg, codec.EncodedFormat);

            Assert.True(encoded);
        }
예제 #23
0
        protected override async Task OnInit()
        {
            await base.OnInit();

            var stream = new SKManagedStream(SampleMedia.Images.AnimatedHeartGif, true);

            codec  = SKCodec.Create(stream);
            frames = codec.FrameInfo;

            info = codec.Info;
            info = new SKImageInfo(info.Width, info.Height, SKImageInfo.PlatformColorType, SKAlphaType.Premul);

            bitmap = new SKBitmap(info);

            cts = new CancellationTokenSource();

            scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var loop = Task.Run(async() =>
            {
                while (!cts.IsCancellationRequested)
                {
                    var duration = frames[currentFrame].Duration;
                    if (duration <= 0)
                    {
                        duration = 100;
                    }

                    await Task.Delay(duration, cts.Token);

                    // next frame
                    currentFrame++;
                    if (currentFrame >= frames.Length)
                    {
                        currentFrame = 0;
                    }

                    new Task(Refresh).Start(scheduler);
                }
            }, cts.Token);
        }
예제 #24
0
        /// <summary>
        /// Loads an image from a disk file, decoding for the optimal required
        /// size so that we don't load the entire image for a smaller target,
        /// and auto-orienting the bitmap according to the codec origin.
        /// This is faster than the slow method above, because it uses the trick
        /// outlined here:
        /// https://forums.xamarin.com/discussion/88794/fast-way-to-decode-skbitmap-from-byte-jpeg-raw
        /// </summary>
        /// <param name="source"></param>
        /// <param name="desiredWidth"></param>
        /// <returns></returns>
        private SKBitmap LoadOrientedBitmap(FileInfo source, int desiredWidth)
        {
            Stopwatch load = new Stopwatch("SkiaSharpLoad");

            SKCodec     codec = SKCodec.Create(source.FullName);
            SKImageInfo info  = codec.Info;

            // get the scale that is nearest to what we want (eg: jpg returned 512)
            SKSizeI supportedScale = codec.GetScaledDimensions((float)desiredWidth / info.Width);

            // decode the bitmap at the nearest size
            SKImageInfo nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height);
            SKBitmap    bmp     = SKBitmap.Decode(codec, nearest);

            load.Stop();

            // First, auto-orient the bitmap
            var sourceBitmap = AutoOrient(bmp, codec.EncodedOrigin);

            return(sourceBitmap);
        }
예제 #25
0
        public ImageSize GetImageSize(string path)
        {
            if (!_fileSystem.FileExists(path))
            {
                throw new FileNotFoundException("File not found", path);
            }

            using (var s = new SKFileStream(NormalizePath(path, _fileSystem)))
            {
                using (var codec = SKCodec.Create(s))
                {
                    var info = codec.Info;

                    return(new ImageSize
                    {
                        Width = info.Width,
                        Height = info.Height
                    });
                }
            }
        }
예제 #26
0
        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))
                {
                    var codec = SKCodec.Create(stream);

                    // create the bitmap
                    var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack);
                    // decode
                    codec.GetPixels(bitmap.Info, bitmap.GetPixels());

                    origin = codec.Origin;

                    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);
        }
예제 #27
0
        public IBitmapImpl LoadBitmap(System.IO.Stream stream)
        {
            using (var s = new SKManagedStream(stream))
            {
                using (var codec = SKCodec.Create(s))
                {
                    var info   = codec.Info;
                    var bitmap = new SKBitmap(info.Width, info.Height, SKImageInfo.PlatformColorType, info.IsOpaque ? SKAlphaType.Opaque : SKAlphaType.Premul);

                    IntPtr length;
                    var    result = codec.GetPixels(bitmap.Info, bitmap.GetPixels(out length));
                    if (result == SKCodecResult.Success || result == SKCodecResult.IncompleteInput)
                    {
                        return(new BitmapImpl(bitmap));
                    }
                    else
                    {
                        throw new ArgumentException("Unable to load bitmap from provided data");
                    }
                }
            }
        }
예제 #28
0
        public unsafe void ReleaseDataWasInvokedOnlyAfterTheCodecWasFinished()
        {
            var path  = Path.Combine(PathToImages, "color-wheel.png");
            var bytes = File.ReadAllBytes(path);

            var released = false;

            fixed(byte *b = bytes)
            {
                var data = SKData.Create((IntPtr)b, bytes.Length, (addr, ctx) => released = true);

                var codec = SKCodec.Create(data);

                Assert.NotEqual(SKImageInfo.Empty, codec.Info);

                data.Dispose();
                Assert.False(released, "The SKDataReleaseDelegate was called too soon.");

                codec.Dispose();
                Assert.True(released, "The SKDataReleaseDelegate was not called at all.");
            }
        }
예제 #29
0
        //creates scaled down versions of the image and saves them on disk
        public void CreateThumbnails(Stream imageStream, string filePath)
        {
            //folder for thumbnails
            string dir = Path.Combine(Path.GetDirectoryName(filePath), "thumbnails");

            Directory.CreateDirectory(dir);

            //file name without extensions
            string displayName = Path.GetFileNameWithoutExtension(filePath);

            //file extensions
            string ext = Path.GetExtension(filePath);

            var format = GetFormat(filePath);

            using (var inputStream = new SKManagedStream(imageStream))
                using (var codec = SKCodec.Create(inputStream))
                    using (var original = SKBitmap.Decode(codec))
                        using (var image = HandleOrientation(original, codec.Origin))
                        {
                            foreach (ImageType type in Enum.GetValues(typeof(ImageType)))
                            {
                                int width  = (int)type;
                                int height = (int)Math.Round(width * ((float)image.Height / image.Width));

                                string thumbnailPath = Path.Combine(dir, $"{displayName}-{width}x{height}{ext}");
                                var    info          = new SKImageInfo(width, height);

                                using (var resized = image.Resize(info, SKBitmapResizeMethod.Lanczos3))
                                    using (var thumb = SKImage.FromBitmap(resized))
                                        using (var fs = new FileStream(thumbnailPath, FileMode.CreateNew, FileAccess.ReadWrite))
                                        {
                                            thumb.Encode(format, Quality)
                                            .SaveTo(fs);
                                        }
                            }
                        }
        }
예제 #30
0
        public async Task PixelateSingleImage(string imagePath, string outputPath)
        {
            _imagePath = imagePath;
            if (File.Exists(outputPath))
            {
                File.Delete(outputPath);
            }

            var outputDirectory = new FileInfo(outputPath).Directory;

            if (outputDirectory != null && !outputDirectory.Exists)
            {
                outputDirectory.Create();
            }

            var bitmap = SKBitmap.Decode(imagePath);
            var origin = SKCodec.Create(imagePath).EncodedOrigin;

            var output = await Pixelate(bitmap, origin, _cloudConnector.AnalyseImage(imagePath));

            await using var fileStream = File.Create(outputPath);
            await output.CopyToAsync(fileStream);
        }