改善版はこちら
こんな感じのgifファイルができる
※画像をクリックして別ウィンドウで見てもらえれば、少しはましに見えるはず。
やりたかったこと
Qiitaにアニメーションを投稿できるようにしようと思い、gifアニメファイルを作る方法を調べた。
今回はGifBitmapEncoder
クラスを使ったが、
この方法は参考サイトにもあるように、
繰り返し回数や遅延時間は指定できません
結果として、速すぎる&繰り返せないものになった。
繰り返せないのは、わりと致命的・・・。
同参考サイトに、ほかの方法も記載されているので、別途試してみたい。
⇒ やってみた
エンコーダ側のソースコード
GifEncoderTest.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Media.Imaging;
using System.Xaml;
class GifEncoderTest
{
public static void CreateAnimatedGif(string savePath, List<string> imageFiles)
{
var encoder = new GifBitmapEncoder();
foreach (string f in imageFiles) {
//画像ファイルからBitmapFrameを作成する
BitmapFrame bmpFrame = BitmapFrame.Create(new Uri(f, UriKind.RelativeOrAbsolute));
encoder.Frames.Add(bmpFrame);
}
var outputFileStrm = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None);
try {
encoder.Save(outputFileStrm);
}
finally {
outputFileStrm.Close();
}
}
[STAThread]
static void Main(string[] args)
{
const int MaxFrames = 1000;
const int FileNameDigits = 3;
if (args.Length != 1) {
Console.WriteLine("Argument error.");
return;
}
string prefix = args[0];
var fileNames = new List<string>();
for (int i=0;i<MaxFrames;i++) {
string s = prefix + i.ToString("D"+FileNameDigits.ToString()) + ".png";
FileInfo fi = new FileInfo(s);
if ( fi.Exists ) {
fileNames.Add(fi.FullName);
}
else {
if ( i==0 ) {
Console.WriteLine("File \"" + fi.FullName + "\" is not found.");
return;
}
break;
}
}
CreateAnimatedGif("out.gif", fileNames);
}
}
コンパイル方法 - バッチファイル
32bit向けと64bit向けが別のdllのようなので、環境に合わせて64を指定した。
csc /nologo ^
/platform:x64 ^
/r:C:\Windows\assembly\NativeImages_v4.0.30319_64\System.Xaml\1e45023cc3b2fa3145024be9518b38d3\System.Xaml.ni.dll ^
/r:C:\Windows\assembly\NativeImages_v4.0.30319_64\WindowsBase\954bf80526cb14a926c4e2335a4e5803\WindowsBase.ni.dll ^
/r:C:\Windows\assembly\NativeImages_v4.0.30319_64\PresentationCore\99085e4311ca84f7357f2d1a2794ca28\PresentationCore.ni.dll ^
%*
文字の画像ファイル1枚1枚を生成するソースコード
注意事項:フォントの著作権に注意(よくわからないのでとりあえず喚起だけ・・)
using System;
using System.Drawing;
using System.Drawing.Imaging;
class SampleBitmapGenerator
{
const string FileNamePrefix = "sample";
const int Width = 200;
const int Height = 200;
const int YAdjust = 10; // アセント(?)による縦方向のずれを無理やり調整
const float FontSize = 150.0f;
const int MaxTitleLength = 100;
[STAThread]
static void Main(string[] args)
{
string title;
Font font = new Font("MS P明朝", FontSize);
if (args.Length == 0) {
title = "gifアニメをC#でやってみた";
}
else {
title = String.Join(" ", args);
}
Bitmap bmp = new Bitmap(Width, Height);
Graphics g = Graphics.FromImage(bmp);
for (int i=0;i<title.Length&&i<MaxTitleLength;i++) {
var sf = new StringFormat();
sf.Alignment = StringAlignment.Center; // 横中央
sf.LineAlignment = StringAlignment.Center; // 縦中央
g.Clear(Color.Black);
g.DrawString(title[i].ToString(), font, Brushes.White, new Point(Width/2,Height/2+YAdjust), sf);
bmp.Save(FileNamePrefix + i.ToString("D3") + ".png", ImageFormat.Png);
}
g.Dispose();
}
}