/// <summary>
        /// Sets an image or gif/apng from a resource path
        /// </summary>
        /// <param name="image">Image component to set the image to</param>
        /// <param name="location">Resource path, file path, or url of image. Can prefix with # to find and use a base game sprite. May need to prefix resource paths with 'AssemblyName:'</param>
        public static void SetImage(this Image image, string location)
        {
            AnimationStateUpdater oldStateUpdater = image.GetComponent <AnimationStateUpdater>();

            if (oldStateUpdater != null)
            {
                MonoBehaviour.DestroyImmediate(oldStateUpdater);
            }
            bool isURL = Uri.TryCreate(location, UriKind.Absolute, out Uri uri);

            if (location.StartsWith("#"))
            {
                string imgName = location.Substring(1);
                try
                {
                    image.sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == imgName);
                }
                catch
                {
                    Logger.log.Error($"Could not find Texture with image name {imgName}");
                }
            }
            else if (IsAnimated(location) || (isURL && IsAnimated(uri.LocalPath)))
            {
                AnimationStateUpdater stateUpdater = image.gameObject.AddComponent <AnimationStateUpdater>();
                stateUpdater.image          = image;
                stateUpdater.controllerData = AnimationController.instance.loadingAnimation;

                if (AnimationController.instance.RegisteredAnimations.TryGetValue(location, out AnimationControllerData animControllerData))
                {
                    stateUpdater.controllerData = animControllerData;
                }
                else
                {
                    Utilities.GetData(location, (byte[] data) => {
                        AnimationLoader.Process((location.EndsWith(".gif") || (isURL && uri.LocalPath.EndsWith(".gif"))) ? AnimationType.GIF : AnimationType.APNG, data, (Texture2D tex, Rect[] uvs, float[] delays, int width, int height) =>
                        {
                            AnimationControllerData controllerData = AnimationController.instance.Register(location, tex, uvs, delays);
                            stateUpdater.controllerData            = controllerData;
                        });
                    });
                }
            }
            else
            {
                AnimationStateUpdater stateUpdater = image.gameObject.AddComponent <AnimationStateUpdater>();
                stateUpdater.image          = image;
                stateUpdater.controllerData = AnimationController.instance.loadingAnimation;

                Utilities.GetData(location, (byte[] data) =>
                {
                    if (stateUpdater != null)
                    {
                        GameObject.DestroyImmediate(stateUpdater);
                    }
                    image.sprite = Utilities.LoadSpriteRaw(data);
                    image.sprite.texture.wrapMode = TextureWrapMode.Clamp;
                });
            }
        }
Ejemplo n.º 2
0
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// On single image cached
        /// </summary>
        /// <param name="p_ID"></param>
        /// <param name="p_Bytes">Result bytes</param>
        /// <param name="p_IsAnimated">Is and animation image</param>
        /// <param name="p_Finally">A callback that occurs after the resource is retrieved. This will always occur even if the resource is already cached.</param>
        /// <param name="p_ForcedHeight">Forced height</param>
        /// <returns></returns>
        private IEnumerator OnSingleImageCached(string p_ID, byte[] p_Bytes, bool p_IsAnimated, Action <EnhancedImageInfo> p_Finally = null, int p_ForcedHeight = -1)
        {
            int l_SpriteWidth  = 0;
            int l_SpriteHeight = 0;

            Sprite l_Sprite = null;

            AnimationControllerData l_AnimControllerData = null;

            if (p_IsAnimated)
            {
                AnimationLoader.Process(AnimationType.GIF, p_Bytes, (p_Texture, p_Atlas, p_Delays, p_Width, p_Height) =>
                {
                    l_AnimControllerData = AnimationController.instance.Register(p_ID, p_Texture, p_Atlas, p_Delays);
                    l_Sprite             = l_AnimControllerData.sprite;
                    l_SpriteWidth        = p_Width;
                    l_SpriteHeight       = p_Height;
                });

                yield return(new WaitUntil(() => l_AnimControllerData != null));
            }
            else
            {
                try
                {
                    l_Sprite       = BeatSaberPlus.Utils.UnityTexture.LoadSpriteRaw(p_Bytes);
                    l_SpriteWidth  = l_Sprite.texture.width;
                    l_SpriteHeight = l_Sprite.texture.height;
                }
                catch (Exception p_Exception)
                {
                    Logger.Instance.Error("Error in OnSingleImageCached");
                    Logger.Instance.Error(p_Exception);
                    l_Sprite = null;
                }
            }

            EnhancedImageInfo l_Result = null;

            if (l_Sprite != null)
            {
                if (p_ForcedHeight != -1)
                {
                    ComputeImageSizeForHeight(ref l_SpriteWidth, ref l_SpriteHeight, p_ForcedHeight);
                }

                l_Result = new EnhancedImageInfo()
                {
                    ImageID            = p_ID,
                    Sprite             = l_Sprite,
                    Width              = l_SpriteWidth,
                    Height             = l_SpriteHeight,
                    AnimControllerData = l_AnimControllerData
                };

                m_CachedImageInfo[p_ID] = l_Result;
            }

            p_Finally?.Invoke(l_Result);
        }
Ejemplo n.º 3
0
        public IEnumerator OnSingleImageCached(byte[] bytes, string id, bool isAnimated, Action <EnhancedImageInfo> Finally = null, int forcedHeight = -1)
        {
            if (bytes.Length == 0)
            {
                Finally(null);
                yield break;
            }

            Sprite sprite = null;
            int    spriteWidth = 0, spriteHeight = 0;
            AnimationControllerData animControllerData = null;

            if (isAnimated)
            {
                AnimationLoader.Process(AnimationType.GIF, bytes, (tex, atlas, delays, width, height) =>
                {
                    animControllerData = AnimationController.instance.Register(id, tex, atlas, delays);
                    sprite             = animControllerData.sprite;
                    spriteWidth        = width;
                    spriteHeight       = height;
                });
                yield return(new WaitUntil(() => animControllerData != null));
            }
            else
            {
                try
                {
                    sprite       = GraphicUtils.LoadSpriteRaw(bytes);
                    spriteWidth  = sprite.texture.width;
                    spriteHeight = sprite.texture.height;
                }
                catch (Exception ex)
                {
                    Logger.log.Error(ex);
                    sprite = null;
                }
            }
            EnhancedImageInfo ret = null;

            if (sprite != null)
            {
                if (forcedHeight != -1)
                {
                    SetImageHeight(ref spriteWidth, ref spriteHeight, forcedHeight);
                }
                ret = new EnhancedImageInfo()
                {
                    ImageId            = id,
                    Sprite             = sprite,
                    Width              = spriteWidth,
                    Height             = spriteHeight,
                    AnimControllerData = animControllerData
                };
                _cachedImageInfo[id] = ret;
            }
            Finally?.Invoke(ret);
        }
Ejemplo n.º 4
0
        public IEnumerator OnSingleImageCached(byte[] bytes, string id, ESCAnimationType animatedType, Action <EnhancedImageInfo> Finally = null, int forcedHeight = -1)
        {
            if (bytes.Length == 0)
            {
                Finally(null);
                yield break;
            }

            Sprite sprite = null;
            int    spriteWidth = 0, spriteHeight = 0;
            AnimationControllerData animControllerData = null;

            switch (animatedType)
            {
            case ESCAnimationType.GIF:
                AnimationLoader.Process(AnimationType.GIF, bytes, (tex, atlas, delays, width, height) =>
                {
                    animControllerData = AnimationController.instance.Register(id, tex, atlas, delays);
                    sprite             = animControllerData.sprite;
                    spriteWidth        = width;
                    spriteHeight       = height;
                });
                yield return(new WaitUntil(() => animControllerData != null));

                break;

            case ESCAnimationType.APNG:
                AnimationLoader.Process(AnimationType.APNG, bytes, (tex, atlas, delays, width, height) =>
                {
                    animControllerData = AnimationController.instance.Register(id, tex, atlas, delays);
                    sprite             = animControllerData.sprite;
                    spriteWidth        = width;
                    spriteHeight       = height;
                });
                yield return(new WaitUntil(() => animControllerData != null));

                break;

            case ESCAnimationType.MAYBE_GIF:
                if (6 <= bytes.Length && (this.ContainBytePattern(bytes, s_animattedGIF89aPattern) || this.ContainBytePattern(bytes, s_animattedGIF87aPattern)))
                {
                    AnimationLoader.Process(AnimationType.GIF, bytes, (tex, atlas, delays, width, height) =>
                    {
                        animControllerData = AnimationController.instance.Register(id, tex, atlas, delays);
                        sprite             = animControllerData.sprite;
                        spriteWidth        = width;
                        spriteHeight       = height;
                    });
                    yield return(new WaitUntil(() => animControllerData != null));
                }
                else
                {
                    try {
                        sprite       = GraphicUtils.LoadSpriteRaw(bytes);
                        spriteWidth  = sprite.texture.width;
                        spriteHeight = sprite.texture.height;
                    }
                    catch (Exception ex) {
                        Logger.Error(ex);
                        sprite = null;
                    }
                }
                break;

            case ESCAnimationType.WEBP:
            case ESCAnimationType.NONE:
            default:
                try {
                    sprite       = GraphicUtils.LoadSpriteRaw(bytes);
                    spriteWidth  = sprite.texture.width;
                    spriteHeight = sprite.texture.height;
                }
                catch (Exception ex) {
                    Logger.Error(ex);
                    sprite = null;
                }
                break;
            }
            var ret = this._imageInfoContaner.Spawn();

            if (sprite != null)
            {
                if (forcedHeight != -1)
                {
                    this.SetImageHeight(ref spriteWidth, ref spriteHeight, forcedHeight);
                }
                ret.ImageId            = id;
                ret.Sprite             = sprite;
                ret.Width              = spriteWidth;
                ret.Height             = spriteHeight;
                ret.AnimControllerData = animControllerData;
                this.CachedImageInfo.TryAdd(id, ret);
            }
            else
            {
                this._imageInfoContaner.Despawn(ret);
            }
            Finally?.Invoke(ret);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Sets an image or gif/apng from a resource path
        /// </summary>
        /// <param name="image">Image component to set the image to</param>
        /// <param name="location">Resource path, file path, or url of image. Can prefix with # to find and use a base game sprite. May need to prefix resource paths with 'AssemblyName:'</param>
        /// <param name="loadingAnimation">Whether a loading animation is shown as a placeholder until the image is loaded</param>
        /// <param name="scaleOptions">If the image should be downscaled and what it should be downscaled to</param>
        /// <param name="callback">Method to call once SetImage has finished</param>
        public static void SetImage(this Image image, string location, bool loadingAnimation, ScaleOptions scaleOptions, Action callback)
        {
            AnimationStateUpdater oldStateUpdater = image.GetComponent <AnimationStateUpdater>();

            if (oldStateUpdater != null)
            {
                MonoBehaviour.DestroyImmediate(oldStateUpdater);
            }

            if (location.Length > 1 && location[0] == '#')
            {
                string imgName = location.Substring(1);
                image.sprite = Utilities.FindSpriteCached(imgName);
                if (image.sprite == null)
                {
                    Logger.log.Error($"Could not find Sprite with image name {imgName}");
                }

                return;
            }


            bool isURL = Uri.TryCreate(location, UriKind.Absolute, out Uri uri);

            if (IsAnimated(location) || isURL && IsAnimated(uri.LocalPath))
            {
                AnimationStateUpdater stateUpdater = image.gameObject.AddComponent <AnimationStateUpdater>();
                stateUpdater.image = image;
                if (loadingAnimation)
                {
                    stateUpdater.controllerData = AnimationController.instance.loadingAnimation;
                }

                if (AnimationController.instance.RegisteredAnimations.TryGetValue(location, out AnimationControllerData animControllerData))
                {
                    stateUpdater.controllerData = animControllerData;
                }
                else
                {
                    Utilities.GetData(location, (byte[] data) =>
                    {
                        AnimationLoader.Process(
                            (location.EndsWith(".gif", StringComparison.OrdinalIgnoreCase) ||
                             (isURL && uri.LocalPath.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))) ? AnimationType.GIF : AnimationType.APNG,

                            data, (Texture2D tex, Rect[] uvs, float[] delays, int width, int height) =>
                        {
                            AnimationControllerData controllerData = AnimationController.instance.Register(location, tex, uvs, delays);
                            stateUpdater.controllerData            = controllerData;
                            callback?.Invoke();
                        });
                    });
                    return;
                }
            }
            else
            {
                AnimationStateUpdater stateUpdater = image.gameObject.AddComponent <AnimationStateUpdater>();
                stateUpdater.image = image;
                if (loadingAnimation)
                {
                    stateUpdater.controllerData = AnimationController.instance.loadingAnimation;
                }

                Utilities.GetData(location, async(byte[] data) =>
                {
                    if (stateUpdater != null)
                    {
                        GameObject.DestroyImmediate(stateUpdater);
                    }

                    if (scaleOptions.ShouldScale)
                    {
                        var imageBytes = await Task.Run(() => DownScaleImage(data, scaleOptions)).ConfigureAwait(false);
                        _ = UnityMainThreadTaskScheduler.Factory.StartNew(() =>
                        {
                            image.sprite = Utilities.LoadSpriteRaw(imageBytes);
                            image.sprite.texture.wrapMode = TextureWrapMode.Clamp;
                        });
                    }
                    else
                    {
                        image.sprite = Utilities.LoadSpriteRaw(data);
                        image.sprite.texture.wrapMode = TextureWrapMode.Clamp;
                    }

                    callback?.Invoke();
                });
                return;
            }
            callback?.Invoke();
        }