画像の色変更機能を追加した、OpaOpaOpasity
OpaOpaOpasity 2.1.0
色変換できるようにした
成果物
2023/07/27追記
グランツーリスモ4 ミッションレース12 4'02.874 ガルフカラー仕様(PCSX2のテクスチャ置換使用)のフォードGT LM レースカー Spec ⅡでMission 12 - YouTube
www.youtube.com
無彩色の変換にも対応したので、黒のラインを橙に変換できた
2023/07/27追記ここまで
ダウンロード先
Releases · gogowaten/OpaOpaOpasity
ここのOpaOpaOpasity2.1.0.0.7z
github.com
動作、作成環境
- Windows 10 Home バージョン 22H2
- Visual Studio Community 2022 Version 17.6.5
- WPF
- C#
- .NET 6.0
変更点
png以外の画像も変換できるようにした
仕様
- 拡張子の文字列で判定している
- 保存形式はpngのみ
色変換機能追加
タブで機能切り替え
色変更設定
使う色空間はHSL
色相、Hue、0から360度で設定
彩度、Saturation、0から1.0で設定、色の鮮やかさ、0で無彩色
輝度(明度)、Lightness、0から1.0で設定、色の明るさ、0でまっくろ、1.0で真っ白、0.5で…原色?あと、アプリでは明度って書いたけど、輝度が正しいみたい?
範囲設定
変換したい色の範囲を指定する
下限と上限の間の色が変換対象になる
0(360)をまたぐ色相の範囲指定
色相は円環なので赤(色相0)を中心に前後30度を指定する場合は
まず、0の後ろ30は0+30=30でいいとして、0のまえは0-30=-30だけど、0は360でもあるので360-30=330なので
下限を330、上限を30、これでいい
変換設定
どんな色にするのかと、計算方法の指定
指定にした場合は、元の色に関係なく指定した値にする。
加算にした場合は、-1.0から+1.0を指定できる。これを元の値に加算する。また、加算した結果が0.0未満や1.0より大きい場合は、それぞれ0.0と1.0に丸める
変換例
全体を青にする
範囲設定
すべてを対象にしたいので
色相:0から360
彩度:0から1
明度:0から1
変換設定
青の色相は240度、鮮やかさや明るさは元の色を引き継ぎたいので、0を加算
色相:240を指定
彩度:0を加算
明度:0を加算
いちごの赤だけ青にする
変換範囲
赤の色相は0、いちごの赤は0ぴったりじゃなくて、0付近なので0から40(橙)にして、彩度と明度はすべてにしてみる
色相:0から40
彩度:0から1
明度:0から1
変換設定、青の色相は240を指定、彩度と明度も元の色を引き継ぎたいので、これもさっきと同じ
これで変換してみると
プランターまで青くなっているけど、これはこれでいいかも
プランターの色は赤と言っても白っぽい、これは明度が高いってことなので、明度の範囲の上限を下げればいい
明度:0から0.5
これで変換
いちごの一部まで除外されてしまったにも関わらず、プランターの大部分は範囲内、ってことは彩度の範囲!
プランターは鮮やかではないので、彩度の下限を上げて0.6、ついでに明度も少し戻して0.8
彩度:0.6から1
明度:0から0.8
この変換でちょうどよくなった
もうひと手間、いちごのつぶつぶが見えるように変換設定の明度を0.2加算
無彩色の色変換
Pixtack紫陽花の色変換ではこれができなかった
その他変更点
エラー減ったはず
並列処理を単純化した
参照したところ
色の変換(カラーコード・RGB・HSV・HSL) / ツール - Hirota Yano
yanohirota.com
RGBとHSLの変換式は、ここの説明がわかりやすかった
RGBとHSLの相互変換コード
MathHSLクラス
using System; namespace OpaOpaOpasity { public class MathHSL { /// <summary> /// RGBをHSLに変換 /// h = 0 to 360.0, s,l = 0 to 1.0 /// 無彩色時のhは360で返す /// </summary> /// <param name="r"></param> /// <param name="g"></param> /// <param name="b"></param> /// <returns></returns> public static (double h, double s, double l) Rgb2Hsl(byte r, byte g, byte b) { byte min = Math.Min(b, Math.Min(r, g)); byte max = Math.Max(b, Math.Max(r, g)); double total = max + min; //輝度L double l = total / 2.0 / 255; double h; double s; //無彩色 if (max == min) { //未定義 h = 0.0; s = 0.0; // //h = 360.0;s = 0.0; } //有彩色 else { double diff = max - min; //色相H if (max == r) { h = (g - b) / diff * 60; if (h < 0) { h += 360.0; } } else if (max == g) { h = (b - r) / diff * 60 + 120; } else { h = (r - g) / diff * 60 + 240; } //彩度S if (0 <= l && l <= 0.5) { s = diff / total; } else { s = diff / (510 - total); } } return (h, s, l); } //色の変換(カラーコード・RGB・HSV・HSL) / ツール - Hirota Yano // https://yanohirota.com/color-converter/ public static (byte r, byte g, byte b) Hsl2Rgb(double h, double s, double l) { double hue = h; if (hue == 360) { hue = 0; } double lum = l; if (0.5 <= l) { lum = 1.0 - l; } double max = 255 * (l + lum * s); double min = 255 * (l - lum * s); double diff = max - min; double rr, gg, bb; if (0 <= hue && hue < 60) { rr = max; gg = FFF(hue); bb = min; } else if (60 <= hue && hue < 120) { rr = FFF(120 - hue); gg = max; bb = min; } else if (120 <= hue && hue < 180) { rr = min; gg = max; bb = FFF(hue - 120); } else if (180 <= hue && hue < 240) { rr = min; gg = FFF(240 - hue); bb = max; } else if (240 <= hue && hue < 300) { rr = FFF(hue - 240); gg = min; bb = max; } else if (300 <= hue && hue < 360) { rr = max; gg = min; bb = FFF(360 - hue); } else { rr = 0; gg = 0; bb = 0; } return ( (byte)Math.Round(rr, MidpointRounding.AwayFromZero), (byte)Math.Round(gg, MidpointRounding.AwayFromZero), (byte)Math.Round(bb, MidpointRounding.AwayFromZero)); double FFF(double x) { return (x / 60 * diff) + min; } } } }
HSLを扱うアプリでは、これをコピペで使っていこうと思う
感想
Pixtack紫陽花ではできなかった無彩色の色変換、これが目的だった!
あとは彩度と明度の加算もなかった(維持と指定のみの)はずなので、これで変換に柔軟性が出せた
見た目や操作性がいまいちだけど、機能は追加できたからヨシ!
関連記事
前回のWPF記事は一週間前
gogowaten.hatenablog.com
最初のOpaOpaOpasityは一ヶ月前
gogowaten.hatenablog.com