static void CalculColors(GifData gifData, int index) { Color[] previousFrame = gifData.previousFrame; if (previousFrame == null) { previousFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; } Color[] currentFrame = gifData.currentFrame; if (currentFrame == null) { currentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; } Color[] transparentFrame = gifData.transparentFrame; if (transparentFrame == null) { transparentFrame = new Color[gifData.canvasWidth * gifData.canvasHeight]; } GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[index]; GifImageDescriptor imageDescriptor = graphicsControlExt.imageDescriptor; GifImageData imageData = imageDescriptor.imageData; int top = imageDescriptor.imageTop; int left = imageDescriptor.imageLeft; int disposalMethod = graphicsControlExt.disposalMethod; int transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1; Color[] colorTabel = imageData.imageDescriptor.localColorTableFlag ? imageData.imageDescriptor.localColorTable : gifData.globalColorTable; 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) { currentFrame[pixelOffset] = colorTabel[colorIndex]; } } } currentFrame.CopyTo(previousFrame, 0); if (disposalMethod == 0 || disposalMethod == 2) { currentFrame = new Color[currentFrame.Length]; imageData.colors = currentFrame; } else { imageData.colors = new Color[currentFrame.Length]; currentFrame.CopyTo(imageData.colors, 0); } gifData.previousFrame = previousFrame; gifData.currentFrame = currentFrame; gifData.transparentFrame = transparentFrame; }
private void WriteGraphicalControlExtension(ImageBase image, EndianBinaryWriter writer, int transparencyIndex) { // TODO: Check transparency logic. bool hasTransparent = transparencyIndex > -1; DisposalMethod disposalMethod = hasTransparent ? DisposalMethod.RestoreToBackground : DisposalMethod.Unspecified; GifGraphicsControlExtension extension = new GifGraphicsControlExtension() { DisposalMethod = disposalMethod, TransparencyFlag = hasTransparent, TransparencyIndex = transparencyIndex, DelayTime = image.FrameDelay }; // Reduce the number of writes. byte[] intro = { GifConstants.extensionIntroducer, GifConstants.graphicControlLabel, 4 // size }; writer.Write(intro); PackedField field = new PackedField(); field.SetBits(3, 3, (int)extension.DisposalMethod); // 1-3 : Reserved, 4-6 : Disposal // TODO: Allow this as an option. field.SetBit(6, false); // 7 : User input - 0 = none field.SetBit(7, extension.TransparencyFlag); // 8: Has transparent. writer.Write(field.Byte); writer.Write((ushort)extension.DelayTime); writer.Write((byte)(extension.TransparencyIndex == -1 ? 255 : extension.TransparencyIndex)); writer.Write(GifConstants.terminator); }
private GifGraphicsControlExtension readGraphicsControlExtension(GifData gifData, byte[] bytes, int offset) { GifGraphicsControlExtension gce = new GifGraphicsControlExtension(gifData); gce.disposalMethod = BitHelper.getIntFromPackedByte(bytes[offset + 3], 3, 6); gce.transparentColorFlag = BitHelper.getIntFromPackedByte(bytes[offset + 3], 7, 8) == 1; gce.delayTime = BitHelper.getInt16FromBytes(bytes, offset + 4); gce.transparentColorIndex = bytes[offset + 6]; return(gce); }
private void ReadGraphicalControlExtension() { byte[] buffer = new byte[6]; currentStream.Read(buffer, 0, buffer.Length); byte packed = buffer[1]; graphicsControlExtension = new GifGraphicsControlExtension { DelayTime = BitConverter.ToInt16(buffer, 2), TransparencyIndex = buffer[4], TransparencyFlag = (packed & 0x01) == 1, DisposalMethod = (DisposalMethod)((packed & 0x1C) >> 2) }; }
static void CalculColors(GifData gifData) { 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; int transparencyIndex = graphicsControlExt.transparentColorFlag ? graphicsControlExt.transparentColorIndex : -1; Color[] colorTabel = imageData.imageDescriptor.localColorTableFlag ? imageData.imageDescriptor.localColorTable : gifData.globalColorTable; 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) { currentFrame[pixelOffset] = colorTabel[colorIndex];//imageData.getColor(colorIndex); } } } // Set texture pixels and create sprite // 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]; imageData.colors = currentFrame; } else { imageData.colors = new Color[currentFrame.Length]; currentFrame.CopyTo(imageData.colors, 0); } } }
static List <Texture2D> CreateAnimator(GifData gifData) { List <Texture2D> sprites = new List <Texture2D>(); // Create sprites for (int i = 0; i < gifData.graphicsControlExtensions.Count; i++) { GifGraphicsControlExtension graphicsControlExt = gifData.graphicsControlExtensions[i]; GifImageDescriptor imageDescriptor = graphicsControlExt.imageDescriptor; GifImageData imageData = imageDescriptor.imageData; Texture2D texture = new Texture2D(gifData.canvasWidth, gifData.canvasHeight); // Set texture pixels and create sprite texture.SetPixels(imageData.colors); texture.Apply(); texture.filterMode = FilterMode.Point; sprites.Add(texture); } return(sprites); }
public void CreateNextTexture() { if (textures == null) { textures = new List <Texture2D>(); } int c = decodeCount; for (int i = createCount; i < c; i++) { GifGraphicsControlExtension graphicsControlExt = graphicsControlExtensions[i]; GifImageDescriptor imageDescriptor = graphicsControlExt.imageDescriptor; GifImageData imageData = imageDescriptor.imageData; Texture2D texture = new Texture2D(canvasWidth, canvasHeight); texture.SetPixels(imageData.colors); texture.Apply(); texture.filterMode = FilterMode.Point; textures.Add(texture); } createCount = c; }
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; }
public void Set(GifGraphicsControlExtension.GraphicsControlExtension g, GifImageDescriptor.ImageDescriptor id, GifImageData.ImageData d) { GCE = g; desciptor = id; data = d; }
private void ReadGraphicalControlExtension() { byte[] buffer = new byte[6]; _stream.Read(buffer, 0, buffer.Length); byte packed = buffer[1]; _graphicsControl = new GifGraphicsControlExtension(); _graphicsControl.DelayTime = BitConverter.ToInt16(buffer, 2); _graphicsControl.TransparencyIndex = buffer[4]; _graphicsControl.TransparencyFlag = (packed & 0x01) == 1; _graphicsControl.DisposalMethod = (DisposalMethod)((packed & 0x1C) >> 2); }