質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

4258閲覧

C#で画像を合成したときに色が変わる

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2016/01/26 08:29

いつもお世話になります。
C#, Windows7, VisualStudio2013 Express, .NET4.5の組み合わせでFormアプリケーションを作っています。
folderにある画像を暗転したファイルを作ろうと思いました。
そこで次のようなコードを書いたのです。

private void Form1_Load(object sender, EventArgs e) {
string[] files = Directory.GetFiles("images");
foreach (string file in files) {
Bitmap bmp = new Bitmap(file);
//黒いカーテンを描画する
int curtain = -128;
for (int x = 0; x < bmp.Width; x++) {
for (int y = 0; y < bmp.Height; y++) {
//指定したピクセルの色を取得する
Color c = bmp.GetPixel(x, y);
//新しい色を計算する
int newR = Math.Max(0, c.R + curtain);
int newG = Math.Max(0, c.G + curtain);
int newB = Math.Max(0, c.B + curtain);
//新しい色を設定する
bmp.SetPixel(x, y, Color.FromArgb(newR, newG, newB));
}
}
bmp.Save(file + "error.png", System.Drawing.Imaging.ImageFormat.Png);
}
}

処理した結果です。

イメージ説明

左がoriginal, 右がコードで加工したものです。
これを見せたところ、画像によって暗転の色味が違うとクレームされました。
たしかに上右のものに較べて、下右はグレーが浅い(明るい)です。
それでpaint.net(ペイントソフト)を使い、色合いを-70%に加工したのが中央です。
こちらは色味があっているように見えます。

そこで質問。
(1)なぜコードでは暗転がうまくいかなかったのでしょう?
(2)コードで暗転するにはどうすればよいでしょう?

よろしくアドバイスお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

C#

1int curtain = -128; 2 : 3 : 4int newR = Math.Max(0, c.R + curtain); 5int newG = Math.Max(0, c.G + curtain); 6int newB = Math.Max(0, c.B + curtain);

「暗転」の計算方法が間違っています。「黒いカーテン」としてRGB各色から一定値を差し引いていますが、これだと色合いが変わってしまいます。例えば、RGBが[255,128,0]ではオレンジ色ですが、128を引くと[127,0,0]となって暗い赤になってしまいます。

暗転の計算は、明るさを差し引くのではなく「割合」で行わないといけません。

例えば、明るさを70%にしたい場合は以下のようなコードを書きます。

C#

1int brightRate = 70; 2 : 3 : 4int newR = c.R * brightRate / 100; // 0より小さくなることはないのでMath.Maxは不要 5// 以下G,Bも同様

投稿2016/01/26 09:02

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/01/27 04:16

なるほど。暗くするというのは、引き算ではなくて割り算なのですね。 ありがとうございます。
guest

0

アップロードいただいてる画像を拝見する限り、同じような色みなのに違いますね。。
こちらで検証ができず、確信が無いのですが・・・

でも、固定値 -128 を加算しているのは問題かと思います・・・

黒 RGB(0,0,0) と、ピクセルカラー( x, y, z ) を内分する必要があるかと思います。

例えば、黒7割をかぶせたい場合は、残りの3割がピクセルのカラーですから、

黒を混ぜたカラーは (x3/10 , y3/10, z*3/10) になります。

割合を指定するように変更してみたほうが良いと思います。

投稿2016/01/26 09:00

Toyoshima

総合スコア422

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/01/27 03:00

ありがとうございます。 固定値 -128 を加算しているのが問題だったのですね。 「ピクセルカラー( x, y, z ) を内分する」 の意味がわからなかったので、補足していただけるとうれしいです。 xyzはどこからきたのでしょう。 「黒7割をかぶせたい場合は、残りの3割がピクセルのカラー」の 残りの3割の計算方法も知りたいです。 よろしくお願いします。
Toyoshima

2016/01/27 05:13

高校数学で学習する、「内分」になります。 点Aと点BをN:Mに内分する点Cは、 (M×A + N×B) / (N + M) です。 例えば、カラーA( 155, 200, 89 ) に対して カラーB ( 98, 220, 111 ) を60%ブレンドする場合、カラーAが40%、カラーBが60% になりますので、 Rの要素 = 60 * 155 + 40 * 98 / (60+40) = 132.2 Gの要素 = 60 * 200 + 40 * 220 / (60+40) = 208 Bの要素 = 60 * 89 + 40 * 111 / (60 + 40) = 97.8 四捨五入して、(132,208,98) が目的の色になります。 こうすれば、任意の画像どおしを掛け合わせることもできますよ。
退会済みユーザー

退会済みユーザー

2016/01/27 06:22

ありがとうございます。 内分点、外分点の内分ですね。 微妙に思い出してきました。 なるほど。そういうことなのですね。 この方法なら、グレーのカーテンを(ロジックで)用意すれば、暗転できるというわけですね。 あ、それが最初の例ですね。 で、さらに任意の画像を掛け合わせることもできると。 なるほど。 これは楽しそうです。ありがとうございます。
Toyoshima

2016/01/27 06:25

そうです^^ 最初の例では、黒のカラー (0 , 0, 0) とのブレンドだと考えてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問