AnimationEditor - Added ability to export animation as gif

This commit is contained in:
miku-666
2023-08-30 18:42:30 +02:00
parent 44c9679bd7
commit 4ca35a5e92
3 changed files with 50 additions and 34 deletions

View File

@@ -34,6 +34,7 @@ using PckStudio.Properties;
using PckStudio.Internal;
using PckStudio.Internal.Json;
using PckStudio.Helper;
using AnimatedGif;
namespace PckStudio.Forms.Editor
{
@@ -291,7 +292,6 @@ namespace PckStudio.Forms.Editor
diag.Dispose();
}
// Reworked import tool with new Animation classes by Miku
private void importJavaAnimationToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show(
@@ -483,40 +483,23 @@ namespace PckStudio.Forms.Editor
LoadAnimationTreeView();
}
//[System.Runtime.InteropServices.DllImport("gdi32.dll")]
//public static extern bool DeleteObject(IntPtr hObject);
private void gifToolStripMenuItem_Click(object sender, EventArgs e)
private void gifToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show(this, "This feature is still under development", "Coming soon");
return;
var fileDialog = new SaveFileDialog()
{
FileName = _tileName,
Filter = "GIF file|*.gif"
};
if (fileDialog.ShowDialog(this) != DialogResult.OK)
return;
// TODO
//var fileDialog = new SaveFileDialog()
//{
// Filter = "GIF file|*.gif"
//};
//if (fileDialog.ShowDialog(this) != DialogResult.OK)
// return;
//GifBitmapEncoder gifBitmapEncoder = new GifBitmapEncoder();
//foreach (Bitmap texture in currentAnimation.GetTextures())
//{
// var bmp = texture.GetHbitmap();
// var src = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
// bmp,
// IntPtr.Zero,
// System.Windows.Int32Rect.Empty,
// BitmapSizeOptions.FromWidthAndHeight(texture.Width, texture.Height));
// gifBitmapEncoder.Frames.Add(BitmapFrame.Create(src));
// DeleteObject(bmp); // recommended, handle memory leak
//}
//using (var fs = fileDialog.OpenFile())
//{
// gifBitmapEncoder.Save(fs);
//}
using (var gifWriter = AnimatedGif.AnimatedGif.Create(fileDialog.FileName, Animation.GameTickInMilliseconds, repeat: 0))
{
foreach (var frame in _animation.GetInterpolatedFrames())
{
gifWriter.AddFrame(frame.Texture, frame.Ticks * Animation.GameTickInMilliseconds, GifQuality.Bit8);
}
}
}
private void frameTimeandTicksToolStripMenuItem_Click(object sender, EventArgs e)

View File

@@ -21,6 +21,7 @@ using System.Drawing;
using PckStudio.Extensions;
using System.Text;
using System.Collections.ObjectModel;
using System.Linq;
namespace PckStudio.Internal
{
@@ -28,6 +29,8 @@ namespace PckStudio.Internal
{
public const int MinimumFrameTime = 1;
public const int GameTickInMilliseconds = 50;
public static Animation Empty(AnimationCategory category)
{
var animation = new Animation(Array.Empty<Image>(), string.Empty);
@@ -172,7 +175,34 @@ namespace PckStudio.Internal
return new ReadOnlyCollection<Frame>(frames);
}
public IReadOnlyCollection<Image> GetTextures()
public IReadOnlyCollection<Frame> GetInterpolatedFrames()
{
if (Interpolate)
{
return new ReadOnlyCollection<Frame>(InternalGetInterpolatedFrames().ToList());
}
return GetFrames();
}
private IEnumerable<Frame> InternalGetInterpolatedFrames()
{
for (int i = 0; i < FrameCount; i++)
{
Frame currentFrame = frames[i];
Frame nextFrame = frames[0];
if (i + 1 < FrameCount)
nextFrame = frames[i + 1];
for (int tick = 0; tick < currentFrame.Ticks; tick++)
{
double delta = 1.0f - tick / (double)currentFrame.Ticks;
yield return new Frame(currentFrame.Texture.Interpolate(nextFrame.Texture, delta));
}
}
yield break;
}
public IReadOnlyCollection<Image> GetTextures()
{
return textures;
}

View File

@@ -691,6 +691,9 @@
<Content Include="Resources\NoImageFound.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AnimatedGif">
<Version>1.0.5</Version>
</PackageReference>
<PackageReference Include="Costura.Fody">
<Version>5.8.0-alpha0098</Version>
<IncludeAssets>compile; runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>