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;

            int index           = 0;
            int firstDelayValue = -1;

            for (int i = 0; i < frameCount; i++)
            {
                gifImage.SelectActiveFrame(dimension, i);
                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(gifImage.Width, gifImage.Height);
                System.Drawing.Graphics.FromImage(bitmap).DrawImage(gifImage, System.Drawing.Point.Empty);
                LockBitmap frame = new LockBitmap(bitmap);
                frame.LockBits();
                FrameInfo currentFrame = new FrameInfo(bitmap.Width, bitmap.Height);
                if (currentFrame.colors == null)
                {
                    currentFrame.colors = new Color32[frame.Height * frame.Width];
                }
                for (int x = 0; x < frame.Width; x++)
                {
                    for (int y = 0; y < frame.Height; y++)
                    {
                        System.Drawing.Color sourceColor = frame.GetPixel(x, y);
                        currentFrame.colors[(frame.Height - y - 1) * frame.Width + x] = new Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A);
                    }
                }

                int delayPropertyValue = BitConverter.ToInt32(gifImage.GetPropertyItem(20736).Value, index);
                if (firstDelayValue == -1)
                {
                    firstDelayValue = delayPropertyValue;
                }

                currentFrame.delay = delayPropertyValue * 10;
                animationInfo.frames.Add(currentFrame);
                index += 4;

                Thread.Sleep(0);
            }
        }
예제 #2
0
        private static void ProcessingThread(byte[] apngData, AnimationInfo animationInfo)
        {
            APNG.APNG apng       = APNG.APNG.FromStream(new System.IO.MemoryStream(apngData));
            int       frameCount = apng.FrameCount;

            animationInfo.frameCount  = frameCount;
            animationInfo.initialized = true;

            for (int i = 0; i < frameCount; i++)
            {
                Frame frame = apng.Frames[i];
                System.Drawing.Bitmap bitmap     = frame.ToBitmap();
                LockBitmap            lockBitmap = new LockBitmap(bitmap);
                lockBitmap.LockBits();
                FrameInfo frameInfo = new FrameInfo(bitmap.Width, bitmap.Height);
                for (int x = 0; x < frameInfo.width; x++)
                {
                    for (int y = 0; y < frameInfo.height; y++)
                    {
                        System.Drawing.Color sourceColor = lockBitmap.GetPixel(x, y);
                        Color32 lastFrame = new Color32();
                        if (i > 0)
                        {
                            lastFrame = animationInfo.frames.Last().colors[(frameInfo.height - y - 1) * frameInfo.width + x];
                        }

                        if (frame.fcTLChunk.BlendOp == APNG.Chunks.BlendOps.APNGBlendOpSource)
                        {
                            frameInfo.colors[(frameInfo.height - y - 1) * frameInfo.width + x] = new Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A);
                        }
                        if (frame.fcTLChunk.BlendOp == APNG.Chunks.BlendOps.APNGBlendOpOver)
                        {
                            float blendedA = ((sourceColor.A / 255f + (1 - (sourceColor.A / 255f)) * (lastFrame.a / 255f)));
                            float blendedR = ((sourceColor.A / 255f) * (sourceColor.R / 255f) + (1 - (sourceColor.A / 255f)) * (lastFrame.a / 255f) * (lastFrame.r / 255f)) / blendedA;
                            float blendedG = ((sourceColor.A / 255f) * (sourceColor.G / 255f) + (1 - (sourceColor.A / 255f)) * (lastFrame.a / 255f) * (lastFrame.g / 255f)) / blendedA;
                            float blendedB = ((sourceColor.A / 255f) * (sourceColor.B / 255f) + (1 - (sourceColor.A / 255f)) * (lastFrame.a / 255f) * (lastFrame.b / 255f)) / blendedA;

                            frameInfo.colors[(frameInfo.height - y - 1) * frameInfo.width + x] = new Color32((byte)(blendedR * 255), (byte)(blendedG * 255), (byte)(blendedB * 255), (byte)(blendedA * 255));
                        }
                    }
                }
                frameInfo.delay = frame.FrameRate;
                animationInfo.frames.Add(frameInfo);
            }
        }