RustとWebAssemblyでドット絵フィルター作ってみた_修正版


# はじめに

下記で作ったドット絵フィルターを友人に見せたところ

友人「解像度低い映像になっただけやん。。。😑」

と言われたのでリベンジも含めて修正版を投稿します。

https://qiita.com/shisojuice/items/7142c594afd6bdc79b13

前回の成果物のフィルター

![RustとWebAssemblyでドット絵フィルター作ってみた_002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/a4b9d9db-acfb-161c-a55c-4398b3940e46.jpeg)

# プロジェクトの作成

前回作成したドット絵フィルターが微妙な理由は、

色合いがドット絵調ではなかったことがあげられる。😑

なので今回は、色をなるべくドット絵調に近づけてみる。

そもそもドット絵の色って何だろうと思い調べたところ、

下記のようなファミコンカラーパレット(ファミコン52色)と呼ばれる色があるみたいなので

これをベースに色を変更してみる

ファミコンカラーパレットについて

https://www.peconet.org/pages/color/fc52.html


前回作成したもの加えて、

下記でcolorsのrgbが引数のrgbに一番近いものを返し、rgbを変換する。

```rust:lib.rs

// 省略

fn closest_color(r: u32, g: u32, b: u32) -> (u32, u32, u32) {
    let colors = [
        (171, 0, 19),  // 赤みがかった濃いピンク
        (231, 0, 91),  // 鮮やかなピンク
        (255, 119, 183),  // 薄いピンク
        (255, 199, 219),  // とても薄いピンク
        (167, 0, 0),  // 暗い赤
        (219, 43, 0),  // やや暗い赤
        (255, 119, 99),  // 明るい赤
        (255, 191, 179),  // 薄い赤
        (127, 11, 0),  // 暗いオレンジ
        (203, 79, 15),  // やや暗いオレンジ
        (255, 155, 59),  // 明るいオレンジ
        (255, 219, 171),  // 薄いオレンジ
        (67, 47, 0),  // 暗い黄色
        (139, 115, 0),  // やや暗い黄色
        (243, 191, 63),  // 明るい黄色
        (255, 231, 163),  // 薄い黄色
        (0, 71, 0),  // 暗い緑
        (0, 151, 0),  // やや暗い緑
        (131, 211, 19),  // 明るい緑
        (227, 255, 163),  // 薄い緑
        (0, 81, 0),  // 暗い青緑
        (0, 171, 0),  // やや暗い青緑
        (79, 223, 75),  // 明るい青緑
        (171, 243, 191),  // 薄い青緑
        (0, 63, 23),  // 暗いシアン
        (0, 147, 59),  // やや暗いシアン
        (88, 248, 152),  // 明るいシアン
        (179, 255, 207),  // 薄いシアン
        (27, 63, 95),  // 暗い青
        (0, 131, 139),  // やや暗い青
        (0, 235, 219),  // 明るい青
        (159, 255, 243),  // 薄い青
        (39, 27, 143),  // 暗い紫
        (0, 115, 239),  // やや暗い紫
        (63, 191, 255),  // 明るい紫
        (171, 231, 255),  // 薄い紫
        (0, 0, 171),  // 暗い藍色
        (35, 59, 239),  // やや暗い藍色
        (95, 115, 255),  // 明るい藍色
        (199, 215, 255),  // 薄い藍色
        (71, 0, 159),  // 暗いマゼンタ
        (131, 0, 243),  // やや暗いマゼンタ
        (167, 139, 253),  // 明るいマゼンタ
        (215, 203, 255),  // 薄いマゼンタ
        (143, 0, 119),  // 暗いピンク
        (191, 0, 191),  // やや暗いピンク
        (247, 123, 255),  // 明るいピンク
        (255, 199, 255),  // 薄いピンク
        (0, 0, 0),  // 黒
        (117, 117, 117),  // 灰色
        (188, 188, 188),  // 薄い灰色
        (255, 255, 255)  // 白
    ];
    *colors
        .iter()
        .min_by_key(|&&(cr, cg, cb)| color_distance(r, g, b, cr, cg, cb))
        .unwrap()
}

fn color_distance(r1: u32, g1: u32, b1: u32, r2: u32, g2: u32, b2: u32) -> u32 {
    let r_diff = r1 as i32 - r2 as i32;
    let g_diff = g1 as i32 - g2 as i32;
    let b_diff = b1 as i32 - b2 as i32;
    // 3次元空間上の距離を計算
    (r_diff * r_diff + g_diff * g_diff + b_diff * b_diff) as u32
}

// 省略

```

上記のフィルター結果は下記、

元画像（実際には映像）

![RustとWebAssemblyでドット絵フィルター作ってみた_修正版_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/37c0d05b-c5bd-f9b5-79a8-a6f46cb597eb.jpeg)

フィルター適用後

![RustとWebAssemblyでドット絵フィルター作ってみた_修正版_002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/49e362bc-becb-e63f-6745-9a7d2d460477.jpeg)

うーん、スマホの水色がでてない、、、😑

あと、ドット絵調の割には、色が全体的に薄いかもしれない

なので、彩度を上げるフィルターもかけてみる


```rust:lib.rs

// 省略

  for i in 0..width * height {
        let index = i * 4; // RGBAなので4倍

        let r = buffer[index] as f32;
        let g = buffer[index + 1] as f32;
        let b = buffer[index + 2] as f32;

        //　HSLは、色相(Hue)、彩度(Saturation)、明度(Lightness) の3つの要素で色を表現する色空間
        let (h, s, l) = rgb_to_hsl(r, g, b);

        let new_s = s * 2.0; // 2倍に設定
        let new_s = new_s.clamp(0.0, 1.0); // 彩度が1.0まで

        // RGBに変換
        let (new_r, new_g, new_b) = hsl_to_rgb(h, new_s, l);
        buffer[index] = new_r as u8;
        buffer[index + 1] = new_g as u8;
        buffer[index + 2] = new_b as u8;
    }

// 省略

```


元画像（実際には映像）

![RustとWebAssemblyでドット絵フィルター作ってみた_修正版_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/37c0d05b-c5bd-f9b5-79a8-a6f46cb597eb.jpeg)

フィルター適用後

![RustとWebAssemblyでドット絵フィルター作ってみた_修正版_003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/08bb8cd6-710e-e896-d077-315770796e4c.jpeg)

さっきよりは、色が出ていてドット絵調っぽい感じになった。

(まだまだ微妙なところもあるが、、)とりあえず完成！

# 今回の成果物

デモURL

https://shisojuice.github.io/Rust_VideoDotFilter/

ソース

https://github.com/shisojuice/Rust_VideoDotFilter


# まとめ

前回のドット絵フィルターを修正してみた。💪

まだまだ、ドット絵というには微妙な感じなので、、、😥

もう少し調査して近づけたら、また記事にしようと思う。🗒️

※間違い等ありましたら、ご指摘いただけると助かります。