C#でGIFアニメーションを表示する
C# WindowsFormsアプリケーションであればPictureBoxを使うのが一番簡単な方法です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public partial class Form1 : Form { string filePath = @"gifファイルのパス"; public Form1() { InitializeComponent(); // たんに Image image = Image.FromFile(filePath); でもよいが、これではファイルがロックされてしまう MemoryStream stream = new MemoryStream(); byte[] bytes = File.ReadAllBytes(filePath); stream.Write(bytes, 0, bytes.Length); Image image = Image.FromStream(stream); PictureBox pictureBox = new PictureBox(); pictureBox.Parent = this; pictureBox.Width = image.Width; pictureBox.Height = image.Height; pictureBox.Image = image; } } |
PictureBoxを使いたくない場合はこんな方法もあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public partial class Form1 : Form { string filePath = @"gifファイルのパス"; private Bitmap animatedImage; public Form1() { InitializeComponent(); //GIFアニメ画像の読み込み MemoryStream stream = new MemoryStream(); byte[] bytes = File.ReadAllBytes(filePath); stream.Write(bytes, 0, bytes.Length); animatedImage = new Bitmap(stream); //アニメ開始 ImageAnimator.Animate(animatedImage, Image_FrameChanged); DoubleBuffered = true; } void Image_FrameChanged(object sender, EventArgs e) { this.Invalidate(); } protected override void OnPaint(PaintEventArgs e) { //フレームを進める ImageAnimator.UpdateFrames(animatedImage); //画像の表示 e.Graphics.DrawImage(animatedImage, 0, 0); base.OnPaint(e); } } |
この方法ならアニメーションの速度を自由に変えることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public partial class Form1 : Form { private Bitmap animatedImage; string filePath = @"Z:\Downloads\新しいフォルダー (3)\shooting-game.gif"; Timer timer = new Timer(); public Form1() { InitializeComponent(); animatedImage = new Bitmap(filePath); ImageAnimator.Animate(animatedImage, null); DoubleBuffered = true; timer.Tick += Timer_Tick; timer.Interval = 500; // この値を変える timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { this.Invalidate(); } protected override void OnPaint(PaintEventArgs e) { ImageAnimator.UpdateFrames(animatedImage); e.Graphics.DrawImage(animatedImage, 0, 0); base.OnPaint(e); } } |
複数の画像ファイルからgifファイルを生成する
複数の画像ファイルからgifファイルを生成したいときはどうすればいいのでしょうか?
一般的なGIFアニメーションは、GIF Header の後に Application Extension があり、その後に Graphic Control Extension と Image Block が交互に連続する構造になっています。
GIF Headerは画像データをgif形式で保存してそこから拾います。Application Extension は
するのであれば以下のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
public partial class Form1 : Form { void SaveGifFile(string filePath, Bitmap[] bitmaps, int millisecond) { MemoryStream memoryStream = new MemoryStream(); BinaryWriter binaryWriter = new BinaryWriter(new FileStream(filePath, FileMode.Create)); bitmaps[0].Save(memoryStream, ImageFormat.Gif); // GIF Header byte[] bytes = memoryStream.ToArray(); bytes[10] = (byte)(bytes[10] & 0x78); // Global Color Tableを使わない binaryWriter.Write(bytes, 0, 13); // Application Extension byte[] applicationExtension = { 33, 255, 11, 78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48, 3, 1, 0, 0, 0 }; binaryWriter.Write(applicationExtension); // Graphic Control Extension と Image Block WriteGifImg(binaryWriter, bytes, millisecond); for (int i = 1; i < bitmaps.Length; i++) { memoryStream.SetLength(0); bitmaps[i].Save(memoryStream, ImageFormat.Gif); bytes = memoryStream.ToArray(); WriteGifImg(binaryWriter, bytes, millisecond); } // Trailer binaryWriter.Write(bytes[bytes.Length - 1]); binaryWriter.Close(); memoryStream.Dispose(); } public void WriteGifImg(BinaryWriter binaryWriter, byte[] bytes, int millisecond) { byte[] delayTimeBytes = BitConverter.GetBytes(millisecond / 10); // 単位は100分の1秒なので10で割る bytes[785] = delayTimeBytes[0]; bytes[786] = delayTimeBytes[1]; bytes[798] = (byte)(bytes[798] | 0x87); binaryWriter.Write(bytes, 781, 18); binaryWriter.Write(bytes, 13, 768); binaryWriter.Write(bytes, 799, bytes.Length - 800); } } |