「非反復主要色決定アルゴリズムに基づくピクセルアートの生成」を読みながらdartでドット絵っぽくする

はじめに

こういう記事を見た

zenn.dev

その後でこういう記事を見た

blog.3qe.us

同じようなことしてえなあと思ったし、ただ真似するだけではつまらないというスタンスもとても大事だなと思ったものの関数型素養が無いので、別で使えるアルゴリズムあるか探してみた。

ありがたいことに「非反復主要色決定アルゴリズムに基づくピクセルアートの生成」というのに行き当たったのでこれを真似してみた。

ソースはここ

github.com

  • forにforしてforしたりしてるけどそれっぽく動いたから一旦こんなもんでいいやろ
    • つーかこれが限界
  • そもそも処理ミスってるかもしれない
  • プルリクください

webデモはここ kyu-suke.github.io

  • flutter web用にちょっと書き換えたりしてるけどだいたい同じ
  • k-means法との違いを感じるなどしてください

やってること

  1. 元画像をブロックに分ける

縦横hの任意のブロックに元画像を分けていく

  1. 各ブロックの色を決めていく

上記画像の斜線マスを対象に考える。

対角線の画素(赤マスと青マス)の組み合わせで色差が大きい方を基準色として利用する。 この例だと青マスの組み合わせが黒と白で赤マスより色差が大きいので、今回だと黒と白が基準の2色になる。

次にブロック内の各画素の色について、基準色の内で色差が少ない方のグループへ割り振っていく ふんわり図示したのが↓

割り振りが終わったら要素数が多い方の色の平均色をそのブロックの色として確定する ざっくり↓な感じ

全ブロックに同様の処理を行うとそれっぽくなる、というお話。

試してみた物々

お盆

竹やぶ

公園

ししゃも

所感

試してみた感じ

  • 写真に適用するとモザイク味がある
  • 色が細かい画像だと結構潰れがち(それはそう)
    • もしくは無理やり引き伸ばした雰囲気になる
  • たまに結構しっくり来る画像もある
  • いらすとやくらいシンプルなやつだとこうだよねって感じになる
    • お盆とかそんな感じ
  • 色数制限してないなと今更気づいたけどピクセルアート自体に制限は無いからいっかの気持ち

実装周り

CustomPainter らへんの使い方をなんとなく理解できたのは良かった。 所定の座標の色を取得するのに以下をコピペ参考にさせていただいた。

Basic image pixel color detection in Flutter (supports screenshots of the widget tree) · GitHub

ビット演算を理解することなく年を重ねてしまったのでまじで何してるかわかんねえって処理が残ってる。

int abgrToArgb(int argbColor) {
  int r = (argbColor >> 16) & 0xFF;
  int b = argbColor & 0xFF;
  return (argbColor & 0xFF00FF00) | (b << 16) | r;
}

おわり

久々に月報以外の内容を書いた。