Exemplo n.º 1
0
        internal void AddFrame(int index, string path, int delay = 66)
        {
            var reader = new PixelUtil(path.SourceFrom());

            reader.LockBits();

            var channelData = new ImageChannelData(reader.Depth, reader.Pixels, reader.Height, reader.Width, Compress); //TODO: Support for layers with multiple sizes.
            var layerData   = new LayerRecord
            {
                Top    = 0,
                Left   = 0,
                Bottom = (uint)Height, // + top,
                Right  = (uint)Width,  // + left,
                Name   = index.ToString()
            };

            reader.UnlockBitsWithoutCommit();

            //Add the lengths of the channels.
            for (var i = 0; i < channelData.ChannelList.Count; i++)
            {
                layerData.Channels.Add((short)(i - 1), (int)channelData.ChannelList[i].Length + 2); //+ 2 bytes for the compression type.
            }
            LayerAndMask.LayerInfo.ImageChannelDataList.Add(channelData);
            LayerAndMask.LayerInfo.LayerList.Add(layerData);

            //TODO: Add ImageResource info (timeline)
            //ImageResources.ImageResourceList.Add(new ImageResourceBlock(2, "shmd", null));
        }
Exemplo n.º 2
0
        internal GifskiError AddFrame(IntPtr handle, uint index, string path, int delay, double lastTimestamp = 0, bool isLast = false)
        {
            if (Version.Major == 0 && Version.Minor < 9)
            {
                return(_addPngFrame(handle, index, path, (ushort)(delay / 10)));
            }

            //var aa = new FormatConvertedBitmap(path.SourceFrom(), PixelFormats.Rgb24, null, 0);

            var util = new PixelUtil(new FormatConvertedBitmap(path.SourceFrom(), PixelFormats.Rgb24, null, 0));

            util.LockBitsAndUnpad();

            var bytesPerRow = util.Width * 3; //Was ((util.Width * 24 + 31) / 32) * 3

            //if (bytesPerRow % 4 != 0)
            //    bytesPerRow += (4 - (bytesPerRow % 4));

            //Pin the buffer in order to pass the address as parameter later.
            var pinnedBuffer = GCHandle.Alloc(util.Pixels, GCHandleType.Pinned);
            var address      = pinnedBuffer.AddrOfPinnedObject();

            GifskiError result;

            if (Version > new Version(0, 10, 4))
            {
                //First frame receives the delay set of the last frame.
                result = AddFrame2Pixels(handle, index, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, index == 0 ? lastTimestamp : _timeStamp);

                _timeStamp += (delay / 1000d);
            }
            else if (Version.Major == 0 && Version.Minor >= 10)
            {
                result = AddFrame2Pixels(handle, index, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, _timeStamp);

                //As a dirty fix for Gifski 0.10.2, the last frame must be duplicated to preserve the timings.
                if (isLast)
                {
                    _timeStamp += ((delay / 1000d) / 2d);
                    result      = AddFrame2Pixels(handle, index + 1, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, _timeStamp);
                }

                //Frames can't be more than 1 second apart. TODO: Add support for dealing with this issue.
                _timeStamp += (delay / 1000d);
            }
            else
            {
                //Normal delay.
                result = AddFramePixels(handle, index, (uint)util.Width, (uint)bytesPerRow, (uint)util.Height, address, (ushort)delay);
            }

            //The buffer must be unpinned, to free resources.
            pinnedBuffer.Free();
            util.UnlockBitsWithoutCommit();

            return(result);
        }
Exemplo n.º 3
0
        internal GifskiError AddFrame(IntPtr handle, uint index, string path, int delay)
        {
            if (Version.Major == 0 && Version.Minor < 9)
            {
                return(_addPngFrame(handle, index, path, (ushort)(delay / 10)));
            }

            var util = new PixelUtil(new FormatConvertedBitmap(path.SourceFrom(), PixelFormats.Rgb24, null, 0));

            util.LockBits();

            var result = AddFramePixels(handle, index, (uint)util.Width, (uint)((util.Width * 24 + 31) / 32) * 4, (uint)util.Height, util.BackBuffer, (ushort)delay);

            util.UnlockBitsWithoutCommit();

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Copy all necessary files to a new encode folder.
        /// </summary>
        /// <param name="usePadding">True if the file names should have a left pad, to preserve the file ordering.</param>
        /// <param name="copyJson">True if the Project.json file should be copied too.</param>
        /// <param name="useBytes">True if the images should be converted to byte array.</param>
        /// <returns>A list of frames with the new path.</returns>
        internal ExportProject CopyToExport(bool usePadding = false, bool copyJson = false, bool useBytes = false)
        {
            #region Output folder

            var folder = Path.Combine(FullPath, "Encode " + DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss-ff"));

            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }

            #endregion

            var export = new ExportProject();

            if (useBytes)
            {
                export.Frames       = new List <ExportFrame>();
                export.ChunkPath    = Path.Combine(folder, "Chunk");
                export.NewChunkPath = Path.Combine(folder, "NewChunk");

                try
                {
                    //Create chunk file.
                    using (var fileStream = new FileStream(export.ChunkPath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        var pos = 0L;

                        foreach (var info in Frames)
                        {
                            var image = new PixelUtil(info.Path.SourceFrom());
                            image.LockBits();

                            fileStream.WriteBytes(image.Pixels);

                            export.Frames.Add(new ExportFrame
                            {
                                DataPosition = pos,
                                DataLength   = image.Pixels.LongLength,
                                Delay        = info.Delay,
                                Rect         = new Int32Rect(0, 0, image.Width, image.Height),
                                ImageDepth   = image.Depth
                            });

                            //Advances in the position.
                            pos += image.Pixels.LongLength;

                            image.UnlockBitsWithoutCommit();
                        }
                    }
                }
                catch (Exception e)
                {
                    LogWriter.Log(e, "It was impossible to get the image bytes to encode.");
                    throw;
                }

                return(export);
            }

            export.UsesFiles   = true;
            export.FramesFiles = new List <FrameInfo>();

            try
            {
                #region If it's being exported as project, maintain file naming

                if (copyJson)
                {
                    foreach (var info in Frames)
                    {
                        var filename = Path.Combine(folder, Path.GetFileName(info.Path));

                        //Copy the image to the folder.
                        File.Copy(info.Path, filename, true);

                        //Create the new object and add to the list.
                        export.FramesFiles.Add(new FrameInfo(filename, info.Delay));
                    }

                    File.Copy(ProjectPath, Path.Combine(folder, "Project.json"), true);

                    return(export);
                }

                #endregion

                //Detect pad size.
                var pad = usePadding ? (Frames.Count - 1).ToString().Length : 0;

                foreach (var info in Frames)
                {
                    //Changes the path of the image. Writes as an ordered list of files, replacing the old filenames.
                    var filename = Path.Combine(folder, export.FramesFiles.Count.ToString().PadLeft(pad, '0') + ".png");

                    //Copy the image to the folder.
                    File.Copy(info.Path, filename, true);

                    //Create the new object and add to the list.
                    export.FramesFiles.Add(new FrameInfo(filename, info.Delay));
                }
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "It was impossible to copy the files to encode.");
                throw;
            }

            return(export);
        }