cscの作法 その398

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題
aforgeでスクリーンをキャプチャしてgifアニメを作成せよ。

# 参考にしたページ。

https://dobon.net/vb/dotnet/graphics/createanimatedgif.html


# アニメ

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1e8eb8d7-8cb1-569a-eca7-884d82590c3c.gif)


# サンプルコード

```


using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.IO;
using AForge.Video;
using AForge.Video.VFW;

class Program {
	private static byte[] ReadBytes(MemoryStream ms, int count) {
		byte[] bs = new byte[count];
		ms.Read(bs, 0, count);
		return bs;
	}
	private static byte[] GetApplicationExtension(UInt16 loopCount) {
		byte[] bs = new byte[19];
		bs[0] = 0x21;
		bs[1] = 0xFF;
		bs[2] = 0x0B;
		bs[3] = (byte)'N';
		bs[4] = (byte)'E';
		bs[5] = (byte)'T';
		bs[6] = (byte)'S';
		bs[7] = (byte)'C';
		bs[8] = (byte)'A';
		bs[9] = (byte)'P';
		bs[10] = (byte)'E';
		bs[11] = (byte)'2';
		bs[12] = (byte)'.';
		bs[13] = (byte)'0';
		bs[14] = 0x03;
		bs[15] = 0x01;
		byte[] loopCountBytes = BitConverter.GetBytes(loopCount);
		bs[16] = loopCountBytes[0];
		bs[17] = loopCountBytes[1];
		bs[18] = 0x00;
		return bs;
	}
	private static byte[] GetGraphicControlExtension(UInt16 delayTime) {
		byte[] bs = new byte[8];
		bs[0] = 0x21;
		bs[1] = 0xF9;
		bs[2] = 0x04;
		bs[3] = 0x00;
		byte[] delayTimeBytes = BitConverter.GetBytes(delayTime);
		bs[4] = delayTimeBytes[0];
		bs[5] = delayTimeBytes[1];
		bs[6] = 0x00;
		bs[7] = 0x00;
		return bs;
	}
	public static void SaveAnimatedGif(string fileName, Bitmap[] baseImages, UInt16 delayTime, UInt16 loopCount) {
		Console.WriteLine("ok4");
		FileStream writerFs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
		BinaryWriter writer = new BinaryWriter(writerFs);
		MemoryStream ms = new MemoryStream();
		bool hasGlobalColorTable = false;
		int colorTableSize = 0;
		int imagesCount = baseImages.Length;
		Console.WriteLine("ok5");
		for (int i = 0; i < imagesCount; i++)
		{
			Bitmap bmp = baseImages[i];
			bmp.Save(ms, ImageFormat.Gif);
			ms.Position = 0;
			if (i == 0)
			{
				writer.Write(ReadBytes(ms, 6));
				byte[] screenDescriptor = ReadBytes(ms, 7);
				if ((screenDescriptor[4] & 0x80) != 0)
				{
					colorTableSize = screenDescriptor[4] & 0x07;
					hasGlobalColorTable = true;
				}
				else
				{
					hasGlobalColorTable = false;
				}
				screenDescriptor[4] = (byte) (screenDescriptor[4] & 0x78);
				writer.Write(screenDescriptor);
				writer.Write(GetApplicationExtension(loopCount));
			}
			else
			{
				ms.Position += 6 + 7;
			}
			byte[] colorTable = null;
			if (hasGlobalColorTable)
			{
				colorTable = ReadBytes(ms, (int) Math.Pow(2, colorTableSize + 1) * 3);
			}
			writer.Write(GetGraphicControlExtension(delayTime));
			if (ms.GetBuffer()[ms.Position] == 0x21)
			{
				ms.Position += 8;
			}
			byte[] imageDescriptor = ReadBytes(ms, 10);
			if (!hasGlobalColorTable)
			{
				if ((imageDescriptor[9] & 0x80) == 0)
					throw new Exception("Not found color table.");
				colorTableSize = imageDescriptor[9] & 7;
				colorTable = ReadBytes(ms, (int) Math.Pow(2, colorTableSize + 1) * 3);
			}
			imageDescriptor[9] = (byte) (imageDescriptor[9] | 0x80 | colorTableSize);
			writer.Write(imageDescriptor);
			writer.Write(colorTable);
			writer.Write(ReadBytes(ms, (int) (ms.Length - ms.Position - 1)));
			if (i == imagesCount - 1)
			{
				writer.Write((byte) 0x3B);
			}
			ms.SetLength(0);
		}
		ms.Close();
		writer.Close();
		writerFs.Close();
	}
	[STAThread]
	static void Main(string[] args) {
		System.Threading.Thread.Sleep(1000);
		Console.WriteLine("ok0");
		Bitmap[] baseImages = new Bitmap[24];
		ScreenCaptureStream streamVideo = new ScreenCaptureStream(Screen.PrimaryScreen.WorkingArea);
		int i = 0;
		streamVideo.NewFrame += new NewFrameEventHandler((sender, eventArgs) => {
			Console.WriteLine(i);
			baseImages[i] = (Bitmap) eventArgs.Frame.Clone();
			i++;
			if (i > 23)
			{
				Console.WriteLine("ok30");
				SaveAnimatedGif("test.gif", baseImages, 60, 24);
				Console.WriteLine("ok31");
				streamVideo.Stop();
				Console.WriteLine("ok32");
			}
		});
		streamVideo.Start();
		Console.WriteLine("ok2");
	}
}





```


以上。