「Krita」と「Python」のクラスでアニメーション動画を作ろう

2025年1月10日(金)
大西 武 (オオニシ タケシ)
第11回の今回は「Krita」と「Python」のクラスを使ってアニメーションする動画を作る解説をします。

はじめに

今回は、クラスを使ってアニメーション動画を作成します。まず、表示する画像ファイルをファイルダイアログで開きます。それから「アルキメデスの螺旋」に沿って、その画像が1個ずつ追加されていくだけのアニメーションをします。アルキメデスの螺旋とは、要するに渦巻き状の螺旋のことです。

クラスを使って動画の作成

「クラスを使う」と言っても、今までにやってきたことを応用すれば簡単にアニメーション動画を作れます。ゲームプログラミングよりさらに一歩手前の、絵を扱うだけのプログラミングをすることでPython3を簡単に学習するのが本連載の狙いですが、簡単過ぎて物足りないかも知れません。

背景色だけの静止動画

まずは、アニメーションする前にクラスを使って動画を作るテンプレートを作ってみます。単純に第6回の解説をクラス化しただけです。まだ画像ファイルは扱いません。

サンプルをスクリプティングしたら「ウィンドウ」→「ワークスペース」→「Animation」を選択し、画像が90個準備できたら「アニメーションタイムライン」の「▶」でアニメーションを再生できます。まだ静止画像です。

図1:緑色の背景色だけの静止動画

・サンプルスクリプト「class_green.py」
01# モジュール
02import tempfile
03import shutil
04import os.path
05from krita import *
06from PyQt5.Qt import *
07# クラス
08class Animation():
09 # ドキュメント作成
10  def create_doc(self,width,height):
11    self.doc = Krita.instance().createDocument(width, height, "Testing animation", "RGBA", "U8", "", 300.0)
12    Krita.instance().activeWindow().addView(self.doc)
13  # アニメーションフレーム
14  def insertFrames(self, nbFrames):
15    tmpPath = tempfile.mkdtemp()
16    files = []
17    for imgNumber in range(nbFrames):
18      fileName = os.path.join(tmpPath, f"tmp{imgNumber:04}.png")
19      files.append(fileName)
20      image = self.draw_img(imgNumber)
21      image.save(fileName)
22    self.doc.importAnimation(files, 0, 1)
23    self.doc.setFullClipRangeEndTime(nbFrames - 1)
24    shutil.rmtree(tmpPath)
25  # 画像の描画
26  def draw_img(self,number):
27    pixmap = QPixmap(self.doc.bounds().size())
28    pixmap.fill(QColor(0,128,0))
29    return pixmap.toImage()
30  # メイン処理
31  def create(self):
32    self.create_doc(800,800)
33    self.doc.setFramesPerSecond(8)
34    self.insertFrames(90)
35# インスタンスの生成
36ins = Animation()
37ins.create()

【サンプルスクリプトの解説】
「create_doc」メソッドと「insertFrames」メソッドは第6回をクラス化しただけです。
「draw_img」メソッドで背景を緑色に塗り潰します。
「create」メソッドでドキュメントを作成し1秒間に8コマ(8FPS)にセットし、90コマの動画を作成します。
「Animation」クラスのインスタンスを作成し、「create」メソッドを実行します。

読み込んだ画像をアルキメデスの螺旋状に描画する動画

それでは、図2を右クリックメニューで画像を名前を付けて保存してください。この画像使って、この画像が1個ずつ増えていくだけのアニメーションを作ります。

図2:アニメーションに使用する画像(右クリックで保存)

ちょっと工夫したのは、アルキメデスの螺旋状に広がっていくところです。アルキメデスの螺旋は、次の計算式のように円周の角度が回っていくうちに徐々に円の半径が大きくなっていくだけの単純な計算です。

「アルキメデスの螺旋」の計算
求める座標(X,Y)
X = cosθ*円の半径
Y = sinθ*円の半径
円の半径 += 増分
(ただし実際の計算はサンプルスクリプト「class_animation.py」では「translate」メソッドと「rotate」メソッドに内包されている。一般にプログラミング言語の数学ライブラリのsin関数とcos関数は円の半径1とした場合の値が取得できる。長さ1にすることを正規化するという)

図3:アニメーション動画

・サンプルスクリプト「class_animation.py」
01(前略)
02  # 画像ファイルを開く
03  def open_img(self):
04    self.pix = QPixmap(self.doc.bounds().size())
05    filter = str('Supported Files (*.jpg *.png);;All files (*)')
06    fileName = QFileDialog.getOpenFileName(None,str(''),str(''),filter)
07    self.pix.load(fileName[0])
08(中略)
09  # 画像の描画
10  def draw_img(self,number):
11    pixmap = QPixmap(self.doc.bounds().size())
12    pixmap.fill(QColor(Qt.transparent))
13    painter = QPainter()
14    painter.begin(pixmap)
15    cx = int(self.doc.width()/2)
16    cy = int(self.doc.height()/2)
17    for i in range(0,number):
18      painter.save()
19      painter.translate(cx,cy)
20      painter.rotate(i*64)
21      painter.drawPixmap(i*6,0,self.pix)
22      painter.restore()
23    painter.end()
24    return pixmap.toImage()
25  # メイン処理
26  def create(self):
27    self.create_doc(800,800)
28    self.open_img()
29    self.doc.setFramesPerSecond(8)
30    self.insertFrames(90)
31# インスタンスの生成
32ins = Animation()
33ins.create()

【サンプルスクリプトの解説】
「open_img」メソッドでファイルダイアログで画像ファイルを開きます。
「draw_img」メソッドでアルキメデスの螺旋状に画像を1個ずつ描画(「drawPixmap」メソッド)していきます。
「create」メソッドでドキュメントを作成し、ファイルダイアログで画像を開き、8FPSにセットし、90コマのアニメーションを動画にします。

【コラム】Think ITの記事

筆者は「プログラミング」「3DCG」「2DCG」「デザイン」「文筆」「音楽」「動画」など、クリエイティブは全て網羅してきたつもりでした。でも「Think IT」の記事を読んでいると「まだまだ手を付けていない分野が山ほどあるなぁ」と思い知らされます。

これらについては、今後Think ITで解説していきたいと思います。

おわりに

今回は、第6回で解説したアニメーションをクラスを使ってプログラミングする方法を解説しました。さらに、ファイルダイアログで開いた画像でアニメーション動画を作ってみました。

著者
大西 武 (オオニシ タケシ)
1975年香川県生まれ。大阪大学経済学部経営学科中退。プログラミング入門書など30冊以上を商業出版する作家。Microsoftで大賞やNTTドコモでグランプリなど20回以上全国区のコンテストに入賞するアーティスト。オリジナルの間違い探し「3Dクイズ」が全国放送のTVで約10回出題。
https://profile.vixar.jp

連載バックナンバー

開発言語技術解説
第15回

「Krita」と「Python」でUIパーツを使って「ドッキングパネル」を構築する

2025/4/11
第15回の今回は「Krita」のメインUIの右側にあるエリアにドッキングするパネルにUIパーツを配置して構築する解説をします。
開発言語技術解説
第14回

「Krita」と「Python」でプラグインを作ろう

2025/3/21
第14回の今回は「Krita」で「Python」スクリプトを「プラグイン」にしたり、「ショートカットキー」をセットする解説をします。
開発言語技術解説
第13回

「Krita」と「Python」でオリジナルの幾何学模様を作ろう

2025/2/27
第13回の今回は「Krita」の「Python」でダイアログUIにUIパーツを貼り付けて操作できるようにして、オリジナルの幾何学模様を作成できるプログラムを解説します。さらにアニメーションも作ります。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています