Odtwarzacz GIF

0

Witam
Napisałem prosty odtwarzacz GIF

 public partial class MainWindow : Window
    {
        private int counter = 0;
        private int imageCount = 0;
        private System.Drawing.Image img;
        public MainWindow()
        {
            InitializeComponent();
            img = System.Drawing.Image.FromFile("C:\\Users\\kamiś\\Desktop\\file.gif");
            imageCount = img.GetFrameCount(FrameDimension.Time);
            if (imageCount <= 1)
            {
                MessageBox.Show("Nie ma piku");
            }
            else {
                var delay = BitConverter.ToInt32(img.GetPropertyItem(20736).Value,0) * 10;
                DispatcherTimer DT = new DispatcherTimer();
                DT.Interval = TimeSpan.FromMilliseconds(delay);
                DT.Tick += new EventHandler(Tick);
                DT.Start();
            }
        }
        private void Tick(Object sender, EventArgs e) {
            if (counter ==imageCount) {
                counter = 0;
            }
            img.SelectActiveFrame(FrameDimension.Time, counter);
            GIF.Source = ConvertImageToBitmapImage(img);
            counter++;
        }
        public BitmapImage ConvertImageToBitmapImage(System.Drawing.Image img) {
            using (var memory = new MemoryStream()) {
                img.Save(memory, ImageFormat.Png);
                memory.Position = 0;

                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();

                return bitmapImage;
            }
        }
    }
}

Niestety wydaje mi się, że GIF w moim odtwarzaczu pracuje delikatnie wolniej. I tutaj pojawia się moje pytanie. Czy poprawnie pobieram czas trwania klatki z ramki ? Chodzi o ten element kodu

 var delay = BitConverter.ToInt32(img.GetPropertyItem(20736).Value,0) * 10;
0

Używasz tag'u 0x5100, prawda? (tak dla czytelności kodu, może go wrzuć do kodu, a może nawet zdefiniuj & nazwij rzecz po imieniu: PropertyTagFrameDelay).
Z dokumentacji: "time delay, in hundredths of a second, between two frames in an animated GIF image." czyli * 10 powinno dać ms (edit: dopiero rankiem załapałem do robisz ;-) Zagaduję więc że problem może tu być też z rozdzielczością timer'a (domyślnie to chyba 35ms). Może dałoby się to przepisać na jeden wątek z jakimś spinning-em (dla małych delays) I Task.Delay (dla większych)?
Dalej, czekasz na tick, wczytujesz do pamięci, robisz konwersję - to też będzie trwało. Sugeruję wczytać wszystkie klatki, a później po nich iterować.
Przy okazji, do podobnych zadań używałem ImageSharp trochę mniej ręcznie trzeba się narobić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1