「Krita」と「Python」のクラスで画像を加工しよう

2024年12月13日(金)
大西 武 (オオニシ タケシ)
第10回の今回は「Krita」で「Python」のクラスを使ってプログラミングして、開いた画像ファイルに擦りガラス加工などをする解説をします。

はじめに

今回は、これまでとちょっと違い「クラス(class)」を使ってKritaでお絵描きをします。と言っても第3回から出てきた「QColor」や「QPixmap」などもクラスで、自分でスクリプティングする部分でクラスを作るということです。

また「ファイルを開く」ダイアログを使った応用例として、開いた画像をピクセル単位で加工します。1つ目のサンプルスクリプトは開いた画像に市松模様(いわゆるチェック柄)を上書きします。2つ目のサンプルスクリプトは開いた画像のピクセルをランダムに移動して擦りガラスのような加工をします。

本連載でこれまでやってきたことを応用すれば簡単にプログラミングできます。今回の2つのサンプルでは、これまでに加えて、画像を読み込み、1ピクセルずつの色を取得して1ピクセルずつ描いていきます。また、関数をオリジナルのクラスやメソッドに書き換えたり、今までの変数をクラスのプロパティに書き換えたりします。

画像の加工

第7回ではファイルを開くダイアログでファイル名を取得しただけでしたが、今回は取得したファイル名の画像ファイルを開いて加工します。と言っても、画像ファイルを開くには「QImage」クラスの「load」メソッドの引数に画像ファイルのパスを指定するだけです。

画像を加工するには、ピクセル単位で色を変更していきます。ベクトル図形の場合は頂点データがあるのでそれを変形しますが、塗り図形の場合は色のピクセルデータがあるだけなので、色を操作します。

市松模様の加工をする

市松模様は「QImage」クラスの「setPixelColor」メソッドで黒い点を描くだけです。X座標もY座標も偶数のときと、X座標もY座標も奇数のときに黒い点を描けば市松模様になります(図1)。

もっと使えるようにするには、例えば市松模様を新たにレイヤーを作って被せると良いでしょう。市松模様のピクセルサイズや色を変えてみても良いです。

図1:市松模様(200%拡大表示しています)

・サンプルスクリプト「hatching.py」
# モジュール
from PyQt5.Qt import *
# クラス
class Hatching():
  # ドキュメントの作成
  def create_doc(self,width,height):
    self.doc = Krita.instance().createDocument(width, height, "Document name", "RGBA", "U8", "", 300.0)
    Krita.instance().activeWindow().addView(self.doc)
  # 画像ファイルを開く
  def open_img(self):
    pixelBytes = QByteArray()
    self.img = QImage(pixelBytes,0,0,QImage.Format_ARGB32)
    filter = str('Supported Files (*.jpg *.png);;All files (*)')
    fileName = QFileDialog.getOpenFileName(None,str(''),str(''),filter)
    self.img.load(fileName[0])
  # 市松模様の描画
  def draw_img(self):
    for x in range(0,self.img.width()):
      for y in range(0,self.img.height()):
        if (((y%2) + x) % 2) == 0:
          self.img.setPixelColor(x,y,QColor(0,0,0,255))
  # レイヤーのセット
  def set_layer(self):
    root = self.doc.rootNode()
    layer = root.childNodes()[0]
    if self.img.sizeInBytes() == 4 * layer.channels()[0].channelSize() * self.doc.width() * self.doc.height():
      ptr = self.img.bits()
      ptr.setsize(self.img.byteCount())
      layer.setPixelData(QByteArray(ptr.asstring()), 0, 0, self.doc.width() , self.doc.height()) 
    else:
      print('Error')
  # メイン処理
  def create(self):
    self.open_img()
    self.create_doc(self.img.width(),self.img.height())
    self.draw_img()
    self.set_layer()
    self.doc.refreshProjection()
# インスタンスの生成
ins = Hatching()
ins.create()

【サンプルスクリプトの解説】
関数を「create_doc」メソッドと「set_layer」メソッドに書き換え、変数をプロパティに書き換えます。
「open_img」メソッドで「QFileDialog」クラスの「getOpenFileName」スタティックメソッドを使って画像ファイルを指定し、「QImage」クラスの「load」メソッドで画像を開きます。
「draw_img」メソッドで(x,y)が市松模様になる座標だけ黒色のピクセルを塗ります。
「create」メソッドでopen_imgメソッドを呼び出し、開いた画像のサイズでドキュメントを作ってdraw_imgメソッドとset_layerメソッドを呼び出した後、リフレッシュします。

擦りガラスの加工をする

擦りガラス風の加工(図2)をするには、ピクセルをランダムに移動すれば良いだけです。今回はピクセルの(x,y)座標を-5以上5以下だけランダムに移動します。「create_doc」メソッド、「open_img」メソッド、「set_layer」メソッド、「create」メソッドについては、サンプルスクリプト「hatching.py」と全く同じです。

図2:擦りガラス加工(400%拡大表示しています)

・サンプルスクリプト「effect.py」
# モジュール
from PyQt5.Qt import *
import random
# クラス
class Effect():
(中略)
  # ピクセル毎の移動
  def draw_img(self):
    delta = 5
    for i in range(0,1):
      for x in range(delta,self.img.width()-delta):
        for y in range(delta,self.img.height()-delta):
          xx = x + random.randint(-delta,delta)
          yy = y + random.randint(-delta,delta)
          color = self.img.pixelColor(xx,yy)
          self.img.setPixelColor(x,y,color)
(中略)
# インスタンスの生成
ins = Effect()
ins.create()

【サンプルスクリプトの解説】
乱数を扱う「random」モジュールを呼び出します。
今回の2つのサンプルのように初期化の「__init__」メソッドは省略できます。
「draw_img」メソッドで、ピクセル毎に-delta≦(x,y)≦deltaだけランダムにピクセルをコピーして描画します。

おわりに

今回はクラスを使った実例として、「ファイルを開く」ダイアログで開いた画像に市松模様を施したり、ピクセルごとにランダムに移動して擦りガラス風の加工をする方法を解説しました。

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

連載バックナンバー

開発言語技術解説
第10回

「Krita」と「Python」のクラスで画像を加工しよう

2024/12/13
第10回の今回は「Krita」で「Python」のクラスを使ってプログラミングして、開いた画像ファイルに擦りガラス加工などをする解説をします。
開発言語技術解説
第9回

「Krita」と「Python」でクラスの文法を身につけよう

2024/11/22
第9回の今回は「Krita」と「Python」で、オブジェクト指向プログラミングができる「クラス」の文法を解説します。
開発言語技術解説
第8回

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

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

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

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

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

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