AnimationClock を使ってアニメーション動画を作る(4) |
AnimationClock を使用したアニメーションの紹介 |
1.DoubleAnimationUsingKeyFrames を使用したアニメーション(2D)
2.Transform を使った円のアニメーション(2D)
3.指定された経路上で円を運動させるアニメーション(2D)
4.TileMode で描画された画像のアニメーション(2D) (このページ)
5.自公転する立方体のアニメーション(3D)
6.立方体の表示にタイムラグを設けるアニメーション(3D)
7.ClockGroup を使ったアニメーション−基本編(2D)
8.ClockGroup を使ったアニメーション−応用編(2D)
9.残像を形成するアニメーション(2D)
なお、これらの動画は、「ソフト関連Trial−No.109」で紹介しています。
TileMode で描画された画像のアニメーション動画の作成方法(2D) |
1.作成するアニメーションの内容
Canvas 上に TileMode で描画した 50 個の円の、色を赤から青へ変更し、半径を 1 / 2 に縮小するアニメーションです。
色を変更するアニメーションは、通常の ColorAnimation で作成します。
半径を縮小するアニメーションは、円の描画に使う EllipseGeometry の RadiusXProperty と RadiusYProperty に DoubleAnimation を適用して作成します。
各アニメーションから生成した AnimationClock を使って、動画を作成します。
アニメーション作成の画面は以下のようになります。
3D球状オブジェクトの Material に同種のアニメーション手法を適用して作成した動画について、以下のページで紹介しています。
「BallPicture」 シリーズ − 「Tile Mode 1」
「BallPicture」 シリーズ − 「Tile Mode 2」
2.使用した開発環境
第1例 と同じく、以下の開発環境を使用しました。
開発環境:Visual Studio 2010 Professional Edition
.NET Framework:.NET Framework 4 Client Profile
古いバージョンを使いましたが、最新の開発環境でも問題なく使用できると思います。
3.XAMLコード
XAMLコードは 第1例 と基本的に同じなので、省略します。
4.C#コード
C#コードでアニメーションを記述します。
// usingによって名前空間を参照するコードの部分は省略
public partial class MainWindow : Window
{
// コンストラクター
public MainWindow()
{
InitializeComponent();
InitializeWindow();
}
private const double TIME = 2; // アニメーションの所要時間
private AnimationClock _clockColor; // ColorAnimationのAnimationClock
private AnimationClock _clockSizeX; // 横方向サイズ縮小のAnimationClock
private AnimationClock _clockSizeY; // 縦方向サイズ縮小のAnimationClock
// [Avi]ボタンクリックイベント
private void btnAvi_Click(object sender, RoutedEventArgs e)
{
var filepath = GetAviFilePath();
if (0 < filepath.Length)
{
SaveAsAvi(filepath);
MessageBox.Show("OK");
}
}
// [開始]ボタンクリックイベント
private void btnStart_Click(object sender, RoutedEventArgs e)
{
_clockColor.Controller.Begin();
_clockSizeX.Controller.Begin();
_clockSizeY.Controller.Begin();
}
// [停止]ボタンクリックイベント
private void btnStop_Click(object sender, RoutedEventArgs e)
{
_clockColor.Controller.Stop();
_clockSizeX.Controller.Stop();
_clockSizeY.Controller.Stop();
}
// Tile画像とそのアニメーションをDrawingBrushの形で返すメソッド
private DrawingBrush GetDrawingBrush()
{
var db = new DrawingBrush();
db.Viewport = new Rect(0, 0, 0.1, 0.2);
db.TileMode = TileMode.Tile;
var groupD = new DrawingGroup();
// Tile画像枠作成
groupD.Children.Add(new GeometryDrawing(new SolidColorBrush(Colors.White),
null, new RectangleGeometry(new Rect(new Size(1, 1)))));
// Tile画像作成
var brush = new SolidColorBrush(Colors.Red);
var eg = new EllipseGeometry(new Point(0.5, 0.5), 0.4, 0.4);
groupD.Children.Add(new GeometryDrawing(brush, null, eg));
// Tile画像のColorAnimation作成
var ca = new ColorAnimation(Colors.Blue, new Duration(TimeSpan.FromSeconds(TIMER)));
ca.AutoReverse = true;
ca.RepeatBehavior = RepeatBehavior.Forever;
_clockColor = ca.CreateClock();
brush.ApplyAnimationClock(SolidColorBrush.ColorProperty, _clockColor);
_clockColor.Controller.Stop();
// Tile画像のSizeのAnimation作成
var da = new DoubleAnimation(0.2, new Duration(TimeSpan.FromSeconds(TIMER)));
da.AutoReverse = true;
da.RepeatBehavior = RepeatBehavior.Forever;
_clockSizeX = da.CreateClock();
eg.ApplyAnimationClock(EllipseGeometry.RadiusXProperty, _clockSizeX);
_clockSizeX.Controller.Stop();
_clockSizeY = da.CreateClock();
eg.ApplyAnimationClock(EllipseGeometry.RadiusYProperty, _clockSizeY);
_clockSizeY.Controller.Stop();
db.Drawing = groupD;
return db;
}
// Aviファイル保存パス取得
private string GetAviFilePath()
{
// 省略
}
// [InitializeWindow](コンストラクターから呼出し)
private void InitializeWindow()
{
cvs1.Background = GetDrawingBrush();
}
// Aviファイル作成
private void SaveAsAvi(string filepath)
{
var fps = 48; // フレームレート
var totalFrames = (int)(fps * TIME * 2); // 全フレーム数
var secs = Enumerable.Range(0, totalFrames).Select(t => (((double)t) / fps));
var aviManager = new AviFile.AviManager(filepath, false);
AviFile.VideoStream aviStream = null;
var tempFile = "frame.png";
foreach (var sec in secs)
{
_clockColor.Controller.SeekAlignedToLastTick(TimeSpan.FromSeconds(sec),
TimeSeekOrigin.BeginTime);
_clockSizeX.Controller.SeekAlignedToLastTick(TimeSpan.FromSeconds(sec),
TimeSeekOrigin.BeginTime);
_clockSizeY.Controller.SeekAlignedToLastTick(TimeSpan.FromSeconds(sec),
TimeSeekOrigin.BeginTime);
cvs1.UpdateLayout();
cvs1.SaveImage(tempFile); // cvs1の画像をファイルに保存する
var bmp = new System.Drawing.Bitmap(tempFile);
if (aviStream == null)
aviStream = aviManager.AddVideoStream(true, fps, bmp);
else
aviStream.AddFrame(bmp);
bmp.Dispose();
}
aviManager.Close();
_clockColor.Controller.Stop();
_clockSizeX.Controller.Stop();
_clockSizeY.Controller.Stop();
System.IO.File.Delete(tempFile);
}
}
Tile 画像と各アニメーションの生成は[GetDrawingBrush]メソッドで行い、得られた DrawingBrush を cvs1 の Background に[InitializeWindow]メソッドで設定します。
アニメーションの開始は、[開始]ボタンクリックイベント内の、各 AnimationClock の Begin メソッドで行います。
アニメーションの停止は、[停止]ボタンクリックイベント内の、各 AnimationClock の Stop メソッドで行います。。
Aviファイル作成のためにフレーム画像を取り出す操作は、[SaveAsAvi]メソッド内の、各 AnimationClock の SeekAlignedToLastTick メソッドで行います。
[SaveAsAvi]メソッドの中間付近にある cvs1 の SaveImage 拡張メソッドについては、第1例 の記載を参照してください。
ダウンロード |
ここで紹介したアニメーションを作成するプロジェクトファイルは、以下のリンクからダウンロードすることができます。
「Example04_TileMode」プロジェクトファイルのダウンロード
なお、このプロジェクトでは、AVIファイル化用クラスライブラリとして、Code Project の「
A Simple C# Wrapper for the AviFile Library 」からダウンロードして入手した[AviFile.dll]を使用しています。
ダウンロードしたファイルの利用は、全て利用される方の責任で行っていただきます。
作者は十分な注意を払って本ファイルを作成していますが、もし万一、本ファイルの内容に誤りがあっても、
またその利用によって使用パソコンに問題が発生しても、作者は一切責任を負いません。
公開・更新履歴 |
2017/09/01 ページを公開しました。
ご質問・ご意見・ご感想 |
ご質問、ご意見、ご感想等の連絡は、
こちらへ