「Krita」と「Python」でアーティスティックな絵を描こう

2024年8月16日(金)
大西 武 (オオニシ タケシ)
第4回の今回は「Krita」で数学を用いたプログラミングをして、アーティスティックな絵を描く解説をします。

円周上に円を描く

まず円を1個だけ描く練習をしてから、色相を12色に半透明で重ねた12個の円を30度ずつ回転させた位置に描きます。

「プログラミングは数学的というより英語的だ」と言いましたが、英語でも数学を使うようにプログラミングでも数学を使います。3Dプログラミングに比べたら2Dプログラミングの方が頭の中で直感的に想像できる計算だと思います。

1個の円を描く

サンプルスクリプト「cos.py」を書き換えて、サンプルスクリプト「circle.py」のようにスクリプティングして「▷(実行)」ボタンを押せば、1個の白い円が描画されます。「drawEllipse」関数は楕円を描く関数ですが、半径(radius)をXYとも同じ値にすれば正円になります。

図4:1個の円の描画

・サンプルスクリプト「circle.py」
(前略)
# 円の描画
def draw_circle(doc):
  pixmap = QPixmap(doc.bounds().size())
  pixmap.fill(QColor(0,0,0,255))
  painter = QPainter()
  painter.begin(pixmap)
  color = QColor.fromHsl(0, 0, 255, 255)
  brush = QBrush(color)
  painter.setBrush(brush)
  radius = 400
  painter.drawEllipse(QPoint(400,400),radius,radius)
  painter.end()
  return pixmap.toImage()
(中略)
# メイン関数
def begin_draw():
  doc = create_doc(800,800)
  img = draw_circle(doc)
  set_layer(doc,img)
  doc.refreshProjection()
# メイン関数の呼び出し
begin_draw()

【サンプルスクリプトの解説】
「draw_circle」関数で円を描きます。
「QBrush」クラスで塗り潰す色を設定します。
drawEllipse関数で半径が「radius」変数の円を描きます。
「begin_draw」関数で「draw_circle」関数を呼び出します。

円周上に12個の円を描く

サンプルスクリプト「circle.py」を書き換えて、サンプルスクリプト「orbit.py」のようにスクリプティングして「▷(実行)」ボタンを押せば、半径180pxの円周上に12個の円が色相を赤橙黄緑青蘭紫に変えながら描画されます(図5)。oribit(軌道)というファイル名にしたのは、地球が太陽系の軌道上を公転しているのに似ていると思ったからです。

平行移動や回転やスケーリングの変形には行列を用います。ただし中身はメソッドが用意されているので、数値さえ渡せば勝手に計算してくれます。こちらの回転(「rotate」メソッド)ではラジアンではなく、360度で表す角度を引数に渡します。

図5:円周上に12個の円を描画

・サンプルスクリプト「orbit.py」
(前略)
# 円の描画
def draw_circle(doc):
  pixmap = QPixmap(doc.bounds().size())
  pixmap.fill(QColor(0,0,0,255))
  painter = QPainter()
  painter.begin(pixmap)
  painter.setRenderHint(QPainter.Antialiasing,True)
  pen = QPen(QColor(0,0,0,0))
  painter.setPen(pen)
  cx =int(doc.width()/2)
  cy = int(doc.height()/2)
  radius = 180
  for i in range(0,360,30):
    color = QColor.fromHsl(i, 255, 128, 96)
    brush = QBrush(color)
    painter.setBrush(brush)
    painter.save()
    painter.translate(cx,cy)
    painter.rotate(i)
    painter.drawEllipse(QPoint(180,0),radius,radius)
    painter.restore()
  painter.end()
  return pixmap.toImage()
(後略)

【サンプルスクリプトの解説】
「draw_circle」関数で円を描きます。
「for」文で0~360未満まで30度ずつステップして増えながらループします。
「fromHsl」クラスメソッドの第4引数で半透明の色をQBrushクラスでセットします。
キャンバス中心に変形行列で平行移動(translate)し、Xに180px移動した円を変形行列で回転(rotate)して12個の円を描きます。この際「save」メソッドで変形する前の変形行列を保存し、移動回転した後に「restore(復元する)」メソッドでsaveした変形行列に元に戻して、変形行列をリセットします。

新規追加したレイヤーに円を描く

サンプルスクリプト「orbit.py」を書き換えて、サンプルスクリプト「add_layer.py」のようにスクリプティングして「▷(実行)」ボタンを押せば、新たに「NewLayer」という名前のレイヤーが作成され、そのレイヤーに12個の円が描画されます(図6)。

「createNode(新規レイヤー名,レイヤーの種類)」でレイヤーを新規作成しますが、レイヤーの種類は"paintLayer"など決められた名前でなければ動作しません。

図6:新規追加したレイヤーに円を描画

・サンプルスクリプト「add_layer.py」
(前略)
# レイヤーのセット
def set_layer(doc,img):
  root = doc.rootNode()
  layer = doc.createNode("NewLayer","paintLayer")
  root.addChildNode(layer, None)
  if img.sizeInBytes() == 4 * layer.channels()[0].channelSize() * doc.width() * doc.height():
    ptr = img.bits()
    ptr.setsize(img.byteCount())
    layer.setPixelData(QByteArray(ptr.asstring()), 0, 0, doc.width() , doc.height()) 
  else:
    print('Error')
(後略)

【サンプルスクリプトの解説】
ルートノードを取得します。
「createNode」メソッドでペイントレイヤーを新規作成します。
ルートノードの子に新規レイヤーを追加します。

【コラム】「Pythonの拡張子」

「スクリプター」→「ファイル」→「名前を付けて保存」メニューでファイルを名前を付けて保存する際、自動で「.py」拡張子を付けてくれません。筆者も最初間違ったのですが、スクリプトをファイル名を付けて保存する際に「.py」拡張子を付け忘れると、Pythonを実行するときに動作しません。

おわりに

今回は、三角関数のSINとCOSを用いて円周に関係する計算をして図形を描きました。図形と言ってもラインと円を描いただけです。 2Dや3Dグラフィックスプログラミングをされていない方は、久しぶりに三角関数を見たのではないでしょうか。また、グラフィカルに数学を計算すると、教科書で学習したときほど難しく感じなかったのではと思います。

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

連載バックナンバー

開発言語技術解説
第8回

「Krita」と「Python」でUIパーツを構築してみよう

2024/11/1
第8回の今回は「Krita」で「Python」をプログラミングして、ボタンやスライダーなどのUIパーツを構築する解説をします。
開発言語技術解説
第7回

「Krita」と「Python」でダイアログUIを構築してみよう

2024/10/11
第7回の今回は「Krita」の「Python」で「PyQt5」モジュールの「ウィジェット」を使って、ダイアログUIを構築する解説をします。
開発言語技術解説
第6回

「Krita」と「Python」でアニメーションを描いてみよう

2024/9/24
第6回の今回は「Krita」で「Python」をプログラミングして、正方形が回転するアニメーションを作成する解説をします。

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

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

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

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