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