using DesktopMagic.Api; using DesktopMagic.Api.Settings; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Threading; using System.Threading.Tasks; namespace DesktopMagic.PluginTest; public class GifPlugin : Plugin { [Setting("gif-path", "GIF path")] private readonly TextBox input = new TextBox(""); [Setting("info")] private readonly Label info = new Label(""); private readonly List bitmaps = []; private readonly CancellationTokenSource cancellationTokenSource; private int frameCount = -1; public GifPlugin() { cancellationTokenSource = new CancellationTokenSource(); } public override async void Start() { input.OnValueChanged += Input_OnValueChanged; await LoadGif(); } public override void Stop() { cancellationTokenSource.Cancel(); cancellationTokenSource.Dispose(); bitmaps.Clear(); } public override Bitmap Main() { if (bitmaps.Count == 0) { return null; } frameCount++; if (frameCount >= bitmaps.Count) { frameCount = 0; } return bitmaps[frameCount]; } private async void Input_OnValueChanged() { await LoadGif(); } private Task LoadGif() { return Task.Run(() => { try { if (File.Exists(input.Value)) { info.Value = "Loading..."; Image gif = Image.FromFile(input.Value); PropertyItem item = gif.GetPropertyItem(0x5100); // FrameDelay in libgdiplus UpdateInterval = (item.Value[0] + (item.Value[1] * 256)) * 10; //FrameDelay in ms bitmaps.Clear(); for (int i = 0; i < gif.GetFrameCount(FrameDimension.Time); i++) { cancellationTokenSource.Token.ThrowIfCancellationRequested(); _ = gif.SelectActiveFrame(FrameDimension.Time, i); bitmaps.Add(new Bitmap(gif)); info.Value = $"Loading frame {i + 1} of {gif.GetFrameCount(FrameDimension.Time)}"; } info.Value = string.Empty; } else { info.Value = "File not found!"; } } catch (Exception ex) { info.Value = $"Error: {ex.Message}"; } }, cancellationTokenSource.Token); } }