はじめに
下記で作ったドット絵フィルターを友人に見せたところ
友人「解像度低い映像になっただけやん。。。😑」
と言われたのでリベンジも含めて修正版を投稿します。
前回の成果物のフィルター
プロジェクトの作成
前回作成したドット絵フィルターが微妙な理由は、
色合いがドット絵調ではなかったことがあげられる。😑
なので今回は、色をなるべくドット絵調に近づけてみる。
そもそもドット絵の色って何だろうと思い調べたところ、
下記のようなファミコンカラーパレット(ファミコン52色)と呼ばれる色があるみたいなので
これをベースに色を変更してみる
ファミコンカラーパレットについて
前回作成したもの加えて、
下記でcolorsのrgbが引数のrgbに一番近いものを返し、rgbを変換する。
// 省略
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
}
// 省略
上記のフィルター結果は下記、
元画像(実際には映像)
フィルター適用後
うーん、スマホの水色がでてない、、、😑
あと、ドット絵調の割には、色が全体的に薄いかもしれない
なので、彩度を上げるフィルターもかけてみる
// 省略
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;
}
// 省略
元画像(実際には映像)
フィルター適用後
さっきよりは、色が出ていてドット絵調っぽい感じになった。
(まだまだ微妙なところもあるが、、)とりあえず完成!
今回の成果物
デモURL
ソース
まとめ
前回のドット絵フィルターを修正してみた。💪
まだまだ、ドット絵というには微妙な感じなので、、、😥
もう少し調査して近づけたら、また記事にしようと思う。🗒️
※間違い等ありましたら、ご指摘いただけると助かります。