Example #1
0
        public static UIImage AnimateGif(CGImageSource source, nfloat scale, CGImageThumbnailOptions options, TaskParameter parameters)
        {
            if (source == null)
            {
                return(null);
            }

            var frameCount = source.ImageCount;

            // no need to animate, fail safe.
            if (frameCount <= 1)
            {
                using (var imageRef = source.CreateThumbnail(0, options))
                {
                    return(new UIImage(imageRef, scale, UIImageOrientation.Up));
                }
            }

            var frames         = GetFrames(source, options);
            var delays         = GetDelays(source);
            var totalDuration  = delays.Sum();
            var adjustedFrames = AdjustFramesToSpoofDurations(frames, scale, delays, totalDuration);

            return(UIImage.CreateAnimatedImage(adjustedFrames.ToArray(), totalDuration / 100.0));
        }
Example #2
0
        private static List <CoreGraphics.CGImage> GetFrames(CGImageSource source, CGImageThumbnailOptions options)
        {
            var retval = new List <CoreGraphics.CGImage>();

            for (int i = 0; i < source?.ImageCount; i++)
            {
                var frameImage = source.CreateThumbnail(i, options);
                retval.Add(frameImage);
            }

            return(retval);
        }
Example #3
0
        static CoreGraphics.CGImage[] GetFrames(CGImageSource source, CGImageThumbnailOptions options)
        {
            var retval = new CoreGraphics.CGImage[source.ImageCount];

            for (int i = 0; i < source.ImageCount; i++)
            {
                var frameImage = source.CreateThumbnail(i, options);
                retval[i] = frameImage;
            }

            return(retval);
        }
        // Shamelessly copied from React-Native: https://github.com/facebook/react-native/blob/2cbc9127560c5f0f89ae5aa6ff863b1818f1c7c3/Libraries/Image/RCTImageUtils.m
        public static UIImage ToImage(this NSData data, CGSize destSize, nfloat destScale, RCTResizeMode resizeMode = RCTResizeMode.ScaleAspectFit, ImageInformation imageinformation = null, bool allowUpscale = false)
        {
            using (var sourceRef = CGImageSource.FromData(data))
            {
                var imageProperties = GetImageProperties(sourceRef);

                if (imageProperties == null)
                {
                    throw new BadImageFormatException("Image is null");
                }

                if (imageinformation != null)
                {
                    if (imageProperties.PixelWidth.HasValue && imageProperties.PixelHeight.HasValue)
                    {
                        imageinformation.SetOriginalSize(imageProperties.PixelWidth.Value, imageProperties.PixelHeight.Value);
                    }
                }

                var sourceSize = new CGSize((nfloat)imageProperties.PixelWidth, (nfloat)imageProperties.PixelHeight);

                if (destSize.IsEmpty)
                {
                    destSize = sourceSize;
                    if (destScale <= 0)
                    {
                        destScale = 1;
                    }
                }
                else if (destScale <= 0)
                {
                    destScale = ScaleHelper.Scale;
                }

                // Calculate target size
                CGSize targetSize      = RCTTargetSize(sourceSize, 1, destSize, destScale, resizeMode, allowUpscale);
                CGSize targetPixelSize = RCTSizeInPixels(targetSize, destScale);
                int    maxPixelSize    = (int)Math.Max(
                    Math.Min(sourceSize.Width, targetPixelSize.Width),
                    Math.Min(sourceSize.Height, targetPixelSize.Height)
                    );

                var options = new CGImageThumbnailOptions()
                {
                    ShouldAllowFloat               = true,
                    CreateThumbnailWithTransform   = true,
                    CreateThumbnailFromImageAlways = true,
                    MaxPixelSize = maxPixelSize,
                    ShouldCache  = false,
                };

                UIImage image = null;

                // gif
                if (sourceRef.ImageCount > 1)
                {
                    image = GifHelper.AnimateGif(sourceRef, destScale);
                }
                else
                {
                    // Get thumbnail
                    using (var imageRef = sourceRef.CreateThumbnail(0, options))
                    {
                        if (imageRef != null)
                        {
                            // Return image
                            image = new UIImage(imageRef, destScale, UIImageOrientation.Up);
                        }
                    }
                }

                if (imageinformation != null && image != null)
                {
                    int width  = (int)image.Size.Width;
                    int height = (int)image.Size.Height;
                    imageinformation.SetCurrentSize(width.PointsToPixels(), height.PointsToPixels());
                }

                return(image);
            }
        }
Example #5
0
        public static async Task <IDecodedImage <PImage> > SourceRegfToDecodedImageAsync(NSData nsdata, CGSize destSize, nfloat destScale, Configuration config, TaskParameter parameters, RCTResizeMode resizeMode = RCTResizeMode.ScaleAspectFit, ImageInformation imageinformation = null, bool allowUpscale = false)
        {
            using (var sourceRef = CGImageSource.FromData(nsdata))
            {
                if (sourceRef == null)
                {
                    throw new BadImageFormatException("Decoded image is null or corrupted");
                }

                var imageProperties = sourceRef.GetProperties(0);

                if (imageProperties == null || !imageProperties.PixelWidth.HasValue || !imageProperties.PixelHeight.HasValue)
                {
                    throw new BadImageFormatException("Can't read image size properties. File corrupted?");
                }

                imageinformation.SetOriginalSize(imageProperties.PixelWidth.Value, imageProperties.PixelHeight.Value);

                var sourceSize = new CGSize(imageProperties.PixelWidth.Value, imageProperties.PixelHeight.Value);

                if (destSize.IsEmpty)
                {
                    destSize = sourceSize;
                    if (destScale <= 0)
                    {
                        destScale = 1;
                    }
                }
                else if (destScale <= 0)
                {
                    destScale = ScaleHelper.Scale;
                }

                // Calculate target size
                var targetSize      = RCTTargetSize(sourceSize, 1, destSize, destScale, resizeMode, allowUpscale);
                var targetPixelSize = RCTSizeInPixels(targetSize, destScale);
                var maxPixelSize    = (int)Math.Max(
                    allowUpscale ? targetPixelSize.Width : Math.Min(sourceSize.Width, targetPixelSize.Width),
                    allowUpscale ? targetPixelSize.Height : Math.Min(sourceSize.Height, targetPixelSize.Height)
                    );

                var options = new CGImageThumbnailOptions()
                {
                    ShouldAllowFloat               = true,
                    CreateThumbnailWithTransform   = true,
                    CreateThumbnailFromImageAlways = true,
                    MaxPixelSize = maxPixelSize,
                    ShouldCache  = false,
                };

                PImage image = null;
                IAnimatedImage <PImage>[] images = null;

                // GIF
                if (sourceRef.ImageCount > 1 && config.AnimateGifs && imageinformation.Type != ImageInformation.ImageType.ICO)
                {
                    try
                    {
                        await _gifLock.WaitAsync().ConfigureAwait(false);

                        var frameCount = sourceRef.ImageCount;

                        // no need to animate, fail safe.
                        if (frameCount <= 1)
                        {
                            using (var imageRef = sourceRef.CreateThumbnail(0, options))
                            {
#if __IOS__ || __TVOS__
                                image = new PImage(imageRef, destScale, UIImageOrientation.Up);
#elif __MACOS__
                                image = new PImage(imageRef, CGSize.Empty);
#endif
                            }
                        }

#if __IOS__ || __TVOS__
                        var frames         = GetFrames(sourceRef, options);
                        var delays         = GetDelays(sourceRef);
                        var totalDuration  = delays.Sum();
                        var adjustedFrames = AdjustFramesToSpoofDurations(frames, destScale, delays, totalDuration);
                        var avgDuration    = (double)totalDuration / adjustedFrames.Length;

                        images = new AnimatedImage <PImage> [adjustedFrames.Length];

                        for (int i = 0; i < images.Length; i++)
                        {
                            images[i] = new AnimatedImage <PImage>()
                            {
                                Image = adjustedFrames[i], Delay = (int)avgDuration
                            };
                        }
#elif __MACOS__
                        images = new AnimatedImage <PImage> [frameCount];
                        var delays = GetDelays(sourceRef);

                        for (var i = 0; i < images.Length; i++)
                        {
                            var nsImage = new PImage(sourceRef.CreateThumbnail(i, options), CGSize.Empty);
                            images[i] = new AnimatedImage <PImage>()
                            {
                                Image = nsImage, Delay = delays[i]
                            };
                        }
#endif
                    }
                    finally
                    {
                        _gifLock.Release();
                    }
                }
                else
                {
                    // Get thumbnail
                    using (var imageRef = sourceRef.CreateThumbnail(0, options))
                    {
                        if (imageRef != null)
                        {
#if __IOS__ || __TVOS__
                            image = new PImage(imageRef, destScale, UIImageOrientation.Up);
#elif __MACOS__
                            image = new PImage(imageRef, CGSize.Empty);
#endif
                        }
                    }
                }

                var result = new DecodedImage <PImage>();

                if (images != null && images.Length > 1)
                {
                    result.IsAnimated     = true;
                    result.AnimatedImages = images;

                    if (imageinformation != null)
                    {
                        var width  = (int)images[0].Image.Size.Width;
                        var height = (int)images[0].Image.Size.Height;
                        imageinformation.SetCurrentSize(width.DpToPixels(), height.DpToPixels());
                    }
                }
                else
                {
                    result.Image = image;

                    if (imageinformation != null)
                    {
                        var width  = (int)image.Size.Width;
                        var height = (int)image.Size.Height;
                        imageinformation.SetCurrentSize(width.DpToPixels(), height.DpToPixels());
                    }
                }

                return(result);
            }
        }
        // Shamelessly copied from React-Native: https://github.com/facebook/react-native/blob/2cbc9127560c5f0f89ae5aa6ff863b1818f1c7c3/Libraries/Image/RCTImageUtils.m
        public static UIImage ToImage(this NSData data, CGSize destSize, nfloat destScale, RCTResizeMode resizeMode = RCTResizeMode.ScaleAspectFit, ImageInformation imageinformation = null)
        {
            using (var sourceRef = CGImageSource.FromData(data))
            {
                if (sourceRef == null)
                {
                    return null;
                }

                // Get original image size
                var imageProperties = sourceRef.GetProperties(0);

                if (imageProperties == null)
                {
                    return null;
                }

                if (imageinformation != null)
                {
                    if (imageProperties.PixelWidth.HasValue && imageProperties.PixelHeight.HasValue)
                        imageinformation.SetOriginalSize(imageProperties.PixelWidth.Value, imageProperties.PixelHeight.Value);
                }

                var sourceSize = new CGSize((nfloat)imageProperties.PixelWidth, (nfloat)imageProperties.PixelHeight);

                if (destSize.IsEmpty)
                {
                    destSize = sourceSize;
                    if (destScale <= 0)
                    {
                        destScale = 1;
                    }
                }
                else if (destScale <= 0)
                {
                    destScale = ScaleHelper.Scale;
                }

                // Calculate target size
                CGSize targetSize = RCTTargetSize(sourceSize, 1, destSize, destScale, resizeMode, false);
                CGSize targetPixelSize = RCTSizeInPixels(targetSize, destScale);
                int maxPixelSize = (int)Math.Max(
                    Math.Min(sourceSize.Width, targetPixelSize.Width),
                    Math.Min(sourceSize.Height, targetPixelSize.Height)
                );

                var options = new CGImageThumbnailOptions()
                {
                        ShouldAllowFloat = true,
                        CreateThumbnailWithTransform = true,
                        CreateThumbnailFromImageAlways = true,
                        MaxPixelSize = maxPixelSize,
                        ShouldCache = false,
                };

                // Get thumbnail
                using (var imageRef = sourceRef.CreateThumbnail(0, options))
                {
                    if (imageRef == null)
                    {
                        return null;
                    }

                    // Return image
                    var image = new UIImage(imageRef, destScale, UIImageOrientation.Up);

                    if (imageinformation != null)
                    {
                        int width = (int)image.Size.Width;
                        int height = (int)image.Size.Height;
                        imageinformation.SetCurrentSize(width.PointsToPixels(), height.PointsToPixels());
                    }

                    return image;
                }
            }
        }
Example #7
0
        // Shamelessly copied from React-Native: https://github.com/facebook/react-native/blob/2cbc9127560c5f0f89ae5aa6ff863b1818f1c7c3/Libraries/Image/RCTImageUtils.m
        public static NSImage ToImage(this NSData data, CGSize destSize, nfloat destScale, Configuration config, TaskParameter parameters, RCTResizeMode resizeMode = RCTResizeMode.ScaleAspectFit, ImageInformation imageinformation = null, bool allowUpscale = false)
        {
            using (var sourceRef = CGImageSource.FromData(data))
            {
                if (sourceRef == null)
                {
                    throw new BadImageFormatException("Decoded image is null or corrupted");
                }

                var imageProperties = sourceRef.GetProperties(0);

                if (imageProperties == null || !imageProperties.PixelWidth.HasValue || !imageProperties.PixelHeight.HasValue)
                {
                    throw new BadImageFormatException("Can't read image size properties. File corrupted?");
                }

                imageinformation.SetOriginalSize(imageProperties.PixelWidth.Value, imageProperties.PixelHeight.Value);

                var sourceSize = new CGSize(imageProperties.PixelWidth.Value, imageProperties.PixelHeight.Value);
                if (destSize.IsEmpty)
                {
                    destSize = sourceSize;
                    if (destScale <= 0)
                    {
                        destScale = 1;
                    }
                }
                else if (destScale <= 0)
                {
                    destScale = ScaleHelper.Scale;
                }

                // Calculate target size
                CGSize targetSize      = RCTTargetSize(sourceSize, 1, destSize, destScale, resizeMode, allowUpscale);
                CGSize targetPixelSize = RCTSizeInPixels(targetSize, destScale);
                int    maxPixelSize    = (int)Math.Max(
                    allowUpscale ? targetPixelSize.Width : Math.Min(sourceSize.Width, targetPixelSize.Width),
                    allowUpscale ? targetPixelSize.Height : Math.Min(sourceSize.Height, targetPixelSize.Height)
                    );

                var options = new CGImageThumbnailOptions()
                {
                    ShouldAllowFloat               = true,
                    CreateThumbnailWithTransform   = true,
                    CreateThumbnailFromImageAlways = true,
                    MaxPixelSize = maxPixelSize,
                    ShouldCache  = false,
                };

                NSImage image = null;

                // Get thumbnail
                using (var imageRef = sourceRef.CreateThumbnail(0, options))
                {
                    if (imageRef != null)
                    {
                        // Return image
                        image = new NSImage(imageRef, CGSize.Empty);
                    }
                }


                if (imageinformation != null && image != null)
                {
                    int width  = (int)image.Size.Width;
                    int height = (int)image.Size.Height;
                    imageinformation.SetCurrentSize(width.PointsToPixels(), height.PointsToPixels());
                }

                return(image);
            }
        }