LoginSignup
0
2

More than 5 years have passed since last update.

WPFでコードが綺麗なImageアニメーション

Posted at

このコードで透過GIFの合成も出来るけど、手動の方が3倍早いのでお蔵入り(コードが綺麗≠速い)

AnimationTimelineは、BeginAnimationにセットした時点でデータの入れかえが出来ない様で、ロードしながら動かすと言う用途に向いてない。恐らく自力でードを書いた方が速い(一応やってみたが非同期を入れるとプログラムの大半が書き直しになるのでとりあえず没。)

RenderTargetBitmapを使った場合、各フレームごとにImageSourceのコピーが必要になるためメモリのコピーで時間がかかっている模様。

        private Image Image;

        public void PaintAnimation(BitmapDecoder decoder)
        {
            try
            {

                frameCount = decoder.Frames.Count;
                bitmapFrames = decoder.Frames;
                bmp = decoder.Frames[0];

                int imgWidth = bmp.PixelWidth;
                int imgHeight = bmp.PixelHeight;

                ObjectAnimationUsingKeyFrames animation = new ObjectAnimationUsingKeyFrames();

                long time = 0;
                long span = 1000 * 10;  // = 1ms 


                RenderTargetBitmap rbmp = new RenderTargetBitmap(imgWidth, imgHeight, bmp.DpiX, bmp.DpiY, PixelFormats.Pbgra32);

                for (int i = 0; i < frameCount; i++)
                {
                    BitmapSource fbmp = bitmapFrames[i];
                    BitmapMetadata metadata = fbmp.Metadata as BitmapMetadata;
                    int delay = 33, startX = 0, startY = 0, w = imgWidth, h = imgHeight;

/* 
 *                  Set Delay / startX /startY / w / h in bitmapFrame[i]
 */

                    DrawingVisual drawingVisual = new DrawingVisual();
                    DrawingContext drawingContext = drawingVisual.RenderOpen();
                    drawingContext.DrawImage(fbmp, new Rect(startX, startY, w, h));
                    drawingContext.Close();
                    rbmp.Render(drawingVisual);

                    BitmapSource wbmp = rbmp.Clone();

                    DiscreteObjectKeyFrame key = new DiscreteObjectKeyFrame();
                    key.KeyTime = new TimeSpan(time);
                    key.Value = wbmp;
                    animation.KeyFrames.Add(key);
                    time += delay * span;

                }
                animation.RepeatBehavior = RepeatBehavior.Forever;
                animation.Duration = new TimeSpan(time);
                this.Image.BeginAnimation(Image.SourceProperty, animation);

            }
            catch (Exception e)
            {
                LogWriter.write(e.ToString());
            }
        }
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2