Пример #1
0
        /// <summary>
        /// Creates an animated GIF and writes it to <paramref name="outputStream"/>.
        /// </summary>
        /// <param name="animation"></param>
        /// <param name="outputStream"></param>
        public void Create(ConstRawAnimation animation, Stream outputStream)
        {
            List <Image> rawFrames = new List <Image>();

            // Load each image in the animation.
            foreach (ConstAnimationFrame frame in animation.Frames)
            {
                NpkPath frameImagePath           = frame.Image.ImageFilePath;
                DFO.Common.Images.Image rawFrame = m_imageSource.GetImage(frameImagePath, frame.Image.FrameIndex);
                rawFrames.Add(rawFrame);
            }

            int smallestX;
            int largestX;
            int smallestY;
            int largestY;

            // Frames can have different start positions and widths/heights. Normalize the images to a common coordinate system.
            FrameInfo.GetNormalizedCoordinates(rawFrames.Select(image => image.Attributes), out smallestX, out largestX, out smallestY, out largestY);

            int normalizedWidth  = largestX - smallestX + 1;
            int normalizedHeight = largestY - smallestY + 1;

            List <MagickImage> renderedFrames = new List <MagickImage>();

            try
            {
                // Composite each frame on top of a canvas of normalized width and height.
                for (int frameIndex = 0; frameIndex < animation.Frames.Count; frameIndex++)
                {
                    Image rawFrameImage = rawFrames[frameIndex];
                    ConstAnimationFrame frameAnimationInfo = animation.Frames[frameIndex];

                    MagickImage renderedFrame = RenderFrame(rawFrameImage, frameAnimationInfo, smallestX, largestX, smallestY, largestY, normalizedWidth, normalizedHeight);
                    renderedFrames.Add(renderedFrame);
                }

                // Make the GIF from the frames and write it out to the stream.
                using (MagickImageCollection frameCollection = new GraphicsMagick.MagickImageCollection(renderedFrames))
                {
                    frameCollection.Write(outputStream, MagickFormat.Gif);
                }
            }
            finally
            {
                renderedFrames.ForEach(f => f.Dispose());
            }
        }
Пример #2
0
        private void RefreshFrameList()
        {
            // Clear frame list
            FrameList.Clear();

            // Get current selected inner file
            InnerNpkFile selectedFile = InnerFileList.Current;

            // If none selected nothing else to do here
            if (selectedFile == null)
            {
                return;
            }

            // Get the list of frames. Since it's lazy loaded, there could be a read error.
            List <FrameInfo> frames;

            try
            {
                frames = _editor.Frames[selectedFile.Path].ToList();
            }
            catch (Exception ex)
            {
                // TODO: Better way of displaying than modal?
                // At least get the view to show it instead of the view model
                MessageBox.Show(string.Format("Error reading frames from NPK file: {0}", ex.Message));
                return;
            }

            _smallestX = 0;
            _largestX  = 0;
            _smallestY = 0;
            _largestY  = 0;
            _width     = 1;
            _height    = 1;

            List <FrameInfo> nonLinkFrames = frames.Where(f => f.LinkFrame == null).ToList();

            if (nonLinkFrames.Count > 0)
            {
                FrameInfo.GetNormalizedCoordinates(nonLinkFrames, out _smallestX, out _largestX, out _smallestY, out _largestY);
                _width  = _largestX - _smallestX + 1;
                _height = _largestY - _smallestY + 1;
            }

            // Populate frame list
            for (int frameIndex = 0; frameIndex < frames.Count; frameIndex++)
            {
                FrameInfo frame = frames[frameIndex];
                // if linked frame, follow link
                if (frame.LinkFrame != null)
                {
                    int linkIndex = frame.LinkFrame.Value;
                    if (linkIndex < 0 || linkIndex >= frames.Count)
                    {
                        // TODO: Log error that link is out of range?
                        FrameList.Add(new FrameMetadata(frameIndex, 0, 0, 0, 0, linkIndex));
                    }
                    else
                    {
                        FrameInfo linkedFrame = frames[linkIndex];
                        FrameList.Add(new FrameMetadata(linkedFrame, frameIndex, linkIndex));
                    }
                }
                else
                {
                    FrameList.Add(new FrameMetadata(frame, frameIndex, linkFrameIndex: null));
                }
            }
        }