private void createAnimator(GifData gifData) { List <Sprite> sprites = new List <Sprite>(); GifAnimatorScript animatorScript = gameObject.AddComponent <GifAnimatorScript>(); Color[] previousFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; Color[] currentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; Color[] transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; // Create sprites for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++) { GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i]; GifImageDescriptor imageDescriptor = graphicsControlExt.imageDescriptor; GifImageData imageData = imageDescriptor.imageData; int top = imageDescriptor.imageTop; int left = imageDescriptor.imageLeft; int disposalMethod = graphicsControlExt.disposalMethod; Texture2D texture = new Texture2D(gifData.canvasWidth, gifData.canvasHeight); int transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1; // Determine base pixels if (i == 0) { texture.SetPixels(transparentFrame); } else { if (disposalMethod == 1) { texture.SetPixels(previousFrame); } else if (disposalMethod == 2) { texture.SetPixels(transparentFrame); } else if (disposalMethod == 3) { throw new NotImplementedException("Disposal method 3 is not implemented."); } } // Set pixels from image data for (int j = 0; j < imageDescriptor.imageWidth; j++) { for (int k = 0; k < imageDescriptor.imageHeight; k++) { int x = left + j; int y = (gifData.canvasHeight - 1) - (top + k); int colorIndex = imageData.colorIndices[j + k * imageDescriptor.imageWidth]; int pixelOffset = x + y * gifData.canvasWidth; if (colorIndex != transparencyIndex) { GifColor gifColor = imageData.getColor(colorIndex); currentFrame[pixelOffset] = new Color(gifColor.r / 255f, gifColor.g / 255f, gifColor.b / 255f); } } } // Set texture pixels and create sprite texture.SetPixels(currentFrame); texture.Apply(); texture.filterMode = FilterMode.Point; sprites.Add(Sprite.Create(texture, new Rect(0f, 0f, gifData.canvasWidth, gifData.canvasHeight), new Vector2(1f, 1f))); // Store current frame as previous before continuing, and reset current frame currentFrame.CopyTo(previousFrame, 0); if (disposalMethod == 0 || disposalMethod == 2) { currentFrame = new Color[currentFrame.Length]; } } // Setup animator script animatorScript.sprites = sprites; }
private void createAnimator(GifData gifData) { List <Sprite> sprites = new List <Sprite>(); GifAnimatorScript animatorScript = gameObject.AddComponent <GifAnimatorScript>(); Color[] previousFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; Color[] currentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; Color[] transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; // Create sprites for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++) { GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i]; GifImageDescriptor imageDescriptor = graphicsControlExt.imageDescriptor; GifImageData imageData = imageDescriptor.imageData; int top = imageDescriptor.imageTop; int left = imageDescriptor.imageLeft; int disposalMethod = graphicsControlExt.disposalMethod; Texture2D texture = new Texture2D(gifData.canvasWidth, gifData.canvasHeight); int transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1; // Determine base pixels if (i == 0) { texture.SetPixels(transparentFrame); } else { if (disposalMethod == 1) { texture.SetPixels(previousFrame); } else if (disposalMethod == 2) { texture.SetPixels(transparentFrame); } else if (disposalMethod == 3) { throw new NotImplementedException("Disposal method 3 is not implemented."); } } // Set pixels from image data for (int j = 0; j < imageDescriptor.imageWidth; j++) { for (int k = 0; k < imageDescriptor.imageHeight; k++) { int x = left + j; int y = (gifData.canvasHeight - 1) - (top + k); int colorIndex = imageData.colorIndices[j + k * imageDescriptor.imageWidth]; int pixelOffset = x + y * gifData.canvasWidth; if (colorIndex != transparencyIndex) { GifColor gifColor = imageData.getColor(colorIndex); currentFrame[pixelOffset] = new Color(gifColor.r / 255f, gifColor.g / 255f, gifColor.b / 255f); } } } //float bgMax = 50f / 255; //var transparent = currentFrame.Where(p => p.a == 0); //var bgMeanSum = currentFrame.Aggregate(new float[8], (curSum, color) => //{ // curSum[4] += color.a; // ++curSum[5]; // if (color.a > 0) // { // curSum[6] += color.a; // ++curSum[7]; // } // if (color.r >= bgMax || color.g >= bgMax || color.b >= bgMax) // return curSum; // We are interested on dark colors // curSum[0] += color.r; // curSum[1] += color.g; // curSum[2] += color.b; // ++curSum[3]; // return curSum; //}); //var bgMean = new Color32( // (byte)(bgMeanSum[0] * 255 / bgMeanSum[3]), // (byte)(bgMeanSum[1] * 255 / bgMeanSum[3]), // (byte)(bgMeanSum[2] * 255 / bgMeanSum[3]), // (byte)(bgMeanSum[4] * 255 / bgMeanSum[5])); //Debug.Log( // $"Frame {i} has transparent colors?: {transparent.Any()} || Count: {transparent.Count()} || Background: {bgMean}" + // Environment.NewLine + // $"Solid transparency mean (must be 255): {(byte)(bgMeanSum[6] * 255 / bgMeanSum[7])}"); // Set texture pixels and create sprite texture.SetPixels(currentFrame); texture.Apply(); texture.filterMode = FilterMode.Point; sprites.Add(Sprite.Create(texture, new Rect(0f, 0f, gifData.canvasWidth, gifData.canvasHeight), new Vector2(1f, 1f))); // Store current frame as previous before continuing, and reset current frame currentFrame.CopyTo(previousFrame, 0); if (disposalMethod == 0 || disposalMethod == 2) { currentFrame = new Color[currentFrame.Length]; } } // Setup animator script animatorScript.sprites = sprites; }