public static IEnumerator DownloadAnimated(string imagePath, TextureDownloadInfo imageDownloadInfo, bool isRetry = false)
        {
            if (!CachedTextures.ContainsKey(imageDownloadInfo.spriteIndex))
            {
                byte[] animData        = null;
                int    _waitForFrames  = 10;
                bool   localPathExists = ImageExistsLocally(ref imagePath, imageDownloadInfo, out var localFilePath);

                yield return(Utilities.Download(imagePath, Utilities.DownloadType.Raw, null, (web) =>
                {
                    animData = web.downloadHandler.data;
                }));

                if (animData != null)
                {
                    CachedTextures.TryAdd(imageDownloadInfo.spriteIndex, null);
                    yield return(AnimationDecoder.Process(animData, ChatHandler.Instance.OverlayAnimatedImage, imageDownloadInfo));

                    if (!localPathExists && !imageDownloadInfo.noCache)
                    {
                        ImageSaveQueue.Enqueue(new TextureSaveInfo(localFilePath, animData));
                    }
                }

                yield return(new WaitUntil(() => _waitForFrames-- == 0));
            }
        }
        private static bool ImageExistsLocally(ref string imagePath, TextureDownloadInfo imageDownloadInfo, out string localFilePath)
        {
            string origImagePath = imagePath;

            if (imageDownloadInfo.noCache)
            {
                localFilePath = "";
                return(false);
            }

            string currentPath = Path.Combine(Environment.CurrentDirectory, "Cache", "Images", ImageTypeNames.Get(imageDownloadInfo.type));

            if (!Directory.Exists(currentPath))
            {
                Directory.CreateDirectory(currentPath);
            }

            localFilePath = Path.Combine(currentPath, imageDownloadInfo.spriteIndex);
            if (File.Exists(localFilePath))
            {
                imagePath = localFilePath;
                return(true);
            }
            return(false);
        }
 public void Queue(TextureDownloadInfo emote)
 {
     if (emote.type == ImageType.BTTV_Animated || emote.type == ImageType.Cheermote)
     {
         _animationDownloadQueue.Enqueue(emote);
     }
     else
     {
         _imageDownloadQueue.Enqueue(emote);
     }
 }
예제 #4
0
        public static IEnumerator Download(string imagePath, TextureDownloadInfo imageDownloadInfo, bool isRetry = false)
        {
            if (!CachedTextures.ContainsKey(imageDownloadInfo.spriteIndex))
            {
                int    _waitForFrames = 5;
                Sprite sprite         = null;
                if (imageDownloadInfo.type != ImageType.Emoji)
                {
                    bool localPathExists = ImageExistsLocally(ref imagePath, imageDownloadInfo, out var localFilePath);
                    yield return(Utilities.Download(imagePath, Utilities.DownloadType.Texture, null, (web) =>
                    {
                        sprite = Utilities.LoadSpriteFromTexture(DownloadHandlerTexture.GetContent(web));
                        if (sprite)
                        {
                            if (!localPathExists && !imageDownloadInfo.noCache)
                            {
                                ImageSaveQueue.Enqueue(new TextureSaveInfo(localFilePath, web.downloadHandler.data));
                            }
                        }
                    }));
                }
                else
                {
                    try
                    {
                        sprite = Utilities.LoadSpriteFromResources($"EnhancedStreamChat.Resources.Emojis.{imageDownloadInfo.spriteIndex.ToLower()}");
                    }
                    catch (Exception ex)
                    {
                        Plugin.Log($"An error occurred while trying to load emoji from resources. {ex.ToString()}");
                        yield break;
                    }
                }

                if (sprite)
                {
                    CachedTextures.TryAdd(imageDownloadInfo.spriteIndex, new CachedSpriteData(imageDownloadInfo.type, sprite, sprite.texture.width, sprite.texture.height));
                    yield return(null);

                    ChatHandler.Instance.OverlayImage(sprite, imageDownloadInfo);
                }

                yield return(new WaitUntil(() => _waitForFrames-- == 0));
            }
        }
        public static IEnumerator PreloadAnimatedEmotes()
        {
            int count = 0;

            foreach (string emoteIndex in BTTVAnimatedEmoteIDs.Values)
            {
                if (!Globals.IsAtMainMenu)
                {
                    yield return(new WaitUntil(() => Globals.IsAtMainMenu));
                }

                if (!CachedTextures.ContainsKey(emoteIndex))
                {
                    TextureDownloadInfo downloadInfo = new TextureDownloadInfo("AB" + emoteIndex, ImageType.BTTV_Animated, "!NOTSET!");
                    //Plugin.Log($"Precaching {emoteIndex}");
                    Instance.Queue(downloadInfo);
                    count++;
                    yield return(new WaitUntil(() => !Instance._animationDownloadQueue.Contains(downloadInfo)));
                }
            }
            Plugin.Log($"Precached {count.ToString()} animated emotes successfully!");
        }
예제 #6
0
        public static IEnumerator Process(byte[] gifData, Action <Texture2D, Rect[], float[], bool, int, int, TextureDownloadInfo> callback, TextureDownloadInfo imageDownloadInfo)
        {
            Plugin.Log($"Started decoding gif {imageDownloadInfo.spriteIndex}");

            List <Texture2D> texList   = new List <Texture2D>();
            GifInfo          frameInfo = new GifInfo();
            DateTime         startTime = DateTime.Now;

            Task.Run(() => ProcessingThread(gifData, frameInfo));
            yield return(new WaitUntil(() => { return frameInfo.initialized; }));


            int          textureSize = 2048, width = 0, height = 0;
            Texture2D    texture = null;
            List <float> delays  = new List <float>();

            for (int i = 0; i < frameInfo.frameCount; i++)
            {
                if (frameInfo.frames.Count <= i)
                {
                    yield return(new WaitUntil(() => { return frameInfo.frames.Count > i; }));
                    //Plugin.Log($"Frame {i} is ready for processing! Frame is {frameInfo.frames[i].width}x{frameInfo.frames[i].height}");
                }

                if (texture == null)
                {
                    textureSize = GetTextureSize(frameInfo, i);
                    texture     = new Texture2D(textureSize, textureSize);
                }

                FrameInfo currentFrameInfo = frameInfo.frames[i];
                delays.Add(currentFrameInfo.delay);

                var frameTexture = new Texture2D(currentFrameInfo.width, currentFrameInfo.height, TextureFormat.RGBA32, false);
                frameTexture.wrapMode = TextureWrapMode.Clamp;
                try
                {
                    frameTexture.SetPixels32(currentFrameInfo.colors);
                    frameTexture.Apply(i == 0);
                }
                catch (Exception e)
                {
                    Plugin.Log($"Exception while decoding gif! Frame: {i}, Exception: {e}");
                    yield break;
                }
                yield return(null);

                texList.Add(frameTexture);

                // Instant callback after we decode the first frame in order to display a still image until the animated one is finished loading
                if (i == 0)
                {
                    width  = frameInfo.frames[i].width;
                    height = frameInfo.frames[i].height;
                    callback?.Invoke(frameTexture, texture.PackTextures(new Texture2D[] { frameTexture }, 2, textureSize, true), delays.ToArray(), true, width, height, imageDownloadInfo);
                }
            }
            Rect[] atlas = texture.PackTextures(texList.ToArray(), 2, textureSize, true);

            yield return(null);

            callback?.Invoke(texture, atlas, delays.ToArray(), frameInfo.isDelayConsistent, width, height, imageDownloadInfo);
            Plugin.Log($"Finished decoding gif {imageDownloadInfo.spriteIndex}! Elapsed time: {(DateTime.Now - startTime).TotalSeconds} seconds.");
        }
예제 #7
0
        public static IEnumerator Process(byte[] gifData, Action <Texture2D, Rect[], float, TextureDownloadInfo> callback, TextureDownloadInfo imageDownloadInfo)
        {
            Plugin.Log($"Started decoding gif {imageDownloadInfo.spriteIndex}");

            List <Texture2D> texList   = new List <Texture2D>();
            GifInfo          frameInfo = new GifInfo();
            DateTime         startTime = DateTime.Now;

            Task.Run(() => ProcessingThread(gifData, ref frameInfo));
            yield return(new WaitUntil(() => { return frameInfo.initialized; }));


            int       textureSize = 2048;
            Texture2D texture     = null;
            float     delay       = -1f;

            for (int i = 0; i < frameInfo.frameCount; i++)
            {
                yield return(new WaitUntil(() => { return frameInfo.frames.Count > i; }));

                //Plugin.Log($"Frame {i} is ready for processing! Frame is {frameInfo.frames[i].frame.Width}x{frameInfo.frames[i].frame.Height}");

                if (texture == null)
                {
                    textureSize = GetTextureSize(frameInfo, i);
                    texture     = new Texture2D(textureSize, textureSize);
                }

                FrameInfo currentFrameInfo = frameInfo.frames[i];
                if (delay == -1f)
                {
                    delay = currentFrameInfo.delay;
                }

                var frameTexture = new Texture2D(currentFrameInfo.frame.Width, currentFrameInfo.frame.Height);
                try
                {
                    int       colorIndex = 0;
                    Color32[] colors     = new Color32[currentFrameInfo.frame.Width * currentFrameInfo.frame.Height];
                    for (int x = 0; x < currentFrameInfo.frame.Width; x++)
                    {
                        for (int y = 0; y < currentFrameInfo.frame.Height; y++)
                        {
                            System.Drawing.Color sourceColor = currentFrameInfo.colors[colorIndex];
                            colors[(currentFrameInfo.frame.Height - y - 1) * currentFrameInfo.frame.Width + x] = new Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A);
                            colorIndex++;
                        }
                    }
                    frameTexture.wrapMode = TextureWrapMode.Clamp;
                    frameTexture.SetPixels32(colors);
                    frameTexture.Apply(i == 0);
                }
                catch (Exception e)
                {
                    Plugin.Log($"Exception while decoding gif! Frame: {i}, Exception: {e}");
                    yield break;
                }
                yield return(null);

                texList.Add(frameTexture);

                // Instant callback after we decode the first frame in order to display a still image until the animated one is finished loading
                if (i == 0)
                {
                    callback?.Invoke(frameTexture, texture.PackTextures(new Texture2D[] { frameTexture }, 2, textureSize, true), delay, imageDownloadInfo);
                }
            }
            Rect[] atlas = texture.PackTextures(texList.ToArray(), 2, textureSize, true);

            yield return(null);

            callback?.Invoke(texture, atlas, delay, imageDownloadInfo);
            Plugin.Log($"Finished decoding gif {imageDownloadInfo.spriteIndex}! Elapsed time: {(DateTime.Now - startTime).TotalSeconds} seconds.");
        }