Beispiel #1
0
        private static void ProcessingThread(byte[] gifData, AnimationInfo animationInfo)
        {
            System.Drawing.Image gifImage  = System.Drawing.Image.FromStream(new MemoryStream(gifData));
            FrameDimension       dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
            int frameCount = gifImage.GetFrameCount(dimension);

            animationInfo.frameCount  = frameCount;
            animationInfo.initialized = true;
            animationInfo.frames      = new List <FrameInfo>(frameCount);

            int firstDelayValue = -1;

            var delays = gifImage.GetPropertyItem(20736).Value;

            for (int i = 0; i < frameCount; i++)
            {
                gifImage.SelectActiveFrame(dimension, i);

                using (Bitmap bitmap = new Bitmap(gifImage)) {
                    bitmap.MakeTransparent(System.Drawing.Color.Black);
                    bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);

                    BitmapData frame        = bitmap.LockBits(new Rectangle(Point.Empty, gifImage.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                    FrameInfo  currentFrame = new FrameInfo(frame.Width, frame.Height);

                    Marshal.Copy(frame.Scan0, currentFrame.colors, 0, currentFrame.colors.Length);

                    int delayPropertyValue = BitConverter.ToInt32(delays, i * 4);
                    if (firstDelayValue == -1)
                    {
                        firstDelayValue = delayPropertyValue;
                    }

                    currentFrame.delay = delayPropertyValue * 10;
                    animationInfo.frames.Add(currentFrame);
                }
            }
        }
        public static IEnumerator ProcessAnimationInfo(AnimationInfo animationInfo, Action <Texture2D, Rect[], float[], int, int> callback)
        {
            int       textureSize = AtlasSizeLimit, width = 0, height = 0;
            Texture2D texture = null;

            Texture2D[] texList = new Texture2D[animationInfo.frameCount];
            float[]     delays  = new float[animationInfo.frameCount];

            var lastThrottleTime = Time.realtimeSinceStartup;

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

                    lastThrottleTime = Time.realtimeSinceStartup;
                }

                if (texture == null)
                {
                    textureSize = GetTextureSize(animationInfo, i);
                    texture     = new Texture2D(animationInfo.frames[i].width, animationInfo.frames[i].height);

                    width  = animationInfo.frames[i].width;
                    height = animationInfo.frames[i].height;
                }

                FrameInfo currentFrameInfo = animationInfo.frames[i];
                delays[i] = currentFrameInfo.delay;

                Texture2D frameTexture = new Texture2D(currentFrameInfo.width, currentFrameInfo.height, TextureFormat.BGRA32, false);
                frameTexture.wrapMode = TextureWrapMode.Clamp;
                try
                {
                    frameTexture.LoadRawTextureData(currentFrameInfo.colors);
                }
                catch
                {
                    yield break;
                }

                texList[i] = frameTexture;

                // Allow up to .5ms of thread usage for loading this anim
                if (Time.realtimeSinceStartup > lastThrottleTime + 0.0005f)
                {
                    yield return(null);

                    lastThrottleTime = Time.realtimeSinceStartup;
                }
            }

            Rect[] atlas = texture.PackTextures(texList, 2, textureSize, true);
            foreach (Texture2D frameTex in texList)
            {
                GameObject.Destroy(frameTex);
            }

            callback?.Invoke(texture, atlas, delays, width, height);
        }