これはウィンドウをキャプチャしたものをjpg形式で保存したものです。
タイトルバーの部分だけ色を変更しようとするとムラができてうまくいきません。
そこで似たような色でも同じ色とみなして置換できるようにします。
まずはダイアログに以下を追加します。
そしてColorReplaceFormクラスも修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public partial class ColorReplaceForm : Form { public List<Color> Colors = new List<Color>(); public Color BeforeColor = Color.Empty; public Color AfterColor = Color.Empty; public bool IsBeforeColorTransparent = false; public bool IsAfterColorTransparent = false; // 追加されたフィールド変数 public int differenceR = 0; public int differenceG = 0; public int differenceB = 0; private void ButtonOK_Click(object sender, EventArgs e) { BeforeColor = pictureBox1.BackColor; AfterColor = pictureBox2.BackColor; a if(checkBox1.Checked) IsBeforeColorTransparent = true; if(checkBox2.Checked) IsAfterColorTransparent = true; // 追加された部分 differenceR = (int)numericUpDownR.Value; differenceG = (int)numericUpDownG.Value; differenceB = (int)numericUpDownB.Value; } } |
また新しくGetBitmapReplaceColorメソッドを作成しました。置換処理のまえに置換元の色にRGBの誤差分を加えたものを置換します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public partial class UserControlImage : UserControl { Bitmap GetBitmapReplaceColor(Bitmap sourceBmp, Color beforeColor, Color afterColor, int differenceR, int differenceG, int differenceB) { int width = sourceBmp.Width; int height = sourceBmp.Height; Bitmap newBitmap = new Bitmap(width, height); int minR = beforeColor.R - differenceR; int maxR = beforeColor.R + differenceR; int minG = beforeColor.G - differenceG; int maxG = beforeColor.G + differenceG; int minB = beforeColor.B - differenceB; int maxB = beforeColor.B + differenceB; if(minR < 0) minR = 0; if(maxR > 255) maxR = 255; if(minG < 0) minG = 0; if(maxG > 255) maxG = 255; if(minB < 0) minB = 0; if(maxB > 255) maxB = 255; for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { Color color = sourceBmp.GetPixel(x, y); // 透明と黒を混同しないようにする if(beforeColor != Color.FromArgb(0, 0, 0, 0) && color != Color.FromArgb(0, 0, 0, 0) && minR <= color.R && color.R <= maxR && minG <= color.G && color.G <= maxG && minB <= color.B && color.B <= maxB) newBitmap.SetPixel(x, y, afterColor); else if(beforeColor == Color.FromArgb(0, 0, 0, 0) && color == Color.FromArgb(0, 0, 0, 0)) newBitmap.SetPixel(x, y, afterColor); else newBitmap.SetPixel(x, y, color); } } return newBitmap; } } |
またSetSelectionTransparentメソッドも同様に誤差分の引数を追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
public partial class UserControlImage : UserControl { public Bitmap SetSelectionTransparent(Rectangle rect, Color beforeColor, int differenceR, int differenceG, int differenceB) { Bitmap bmp = Bitmap; int width = bmp.Width; int height = bmp.Height; Bitmap newBmp = new Bitmap(width, height); Bitmap newRectBmp = new Bitmap(rect.Width, rect.Height); int minR = beforeColor.R - differenceR; int maxR = beforeColor.R + differenceR; int minG = beforeColor.G - differenceG; int maxG = beforeColor.G + differenceG; int minB = beforeColor.B - differenceB; int maxB = beforeColor.B + differenceB; if(minR < 0) minR = 0; if(maxR > 255) maxR = 255; if(minG < 0) minG = 0; if(maxG > 255) maxG = 255; if(minB < 0) minB = 0; if(maxB > 255) maxB = 255; for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { Color color = bmp.GetPixel(x, y); if((x < rect.Left || rect.Right <= x) || (y < rect.Top || rect.Bottom <= y)) { newBmp.SetPixel(x, y, color); } else { if(minR <= color.R && color.R <= maxR && minG <= color.G && color.G <= maxG && minB <= color.B && color.B <= maxB) { newBmp.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0)); newRectBmp.SetPixel(x - rect.X, y - rect.Y, Color.FromArgb(0, 0, 0, 0)); } else newBmp.SetPixel(x, y, color); } } } BitmapRectangle.Bitmap = newRectBmp; return newBmp; } } |
あとはメニューの[色の置換(画像全体)]と[色の置換(選択されている部分だけ)]がクリックされたときの処理を修正するだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public partial class Form1 : Form { private void ColorReplaceMenuItem_Click(object sender, EventArgs e) { if(userControlImage1.Bitmap == null) { MessageBox.Show("画像が読み込まれていません", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } ColorReplaceForm form = new ColorReplaceForm(); form.Text = "色の置換(画像全体)"; List<Color> colors = new List<Color>(); if(userControlColorBox1.Color != Color.Empty) colors.Add(userControlColorBox1.Color); if(userControlColorBox2.Color != Color.Empty) colors.Add(userControlColorBox2.Color); if(userControlColorBox3.Color != Color.Empty) colors.Add(userControlColorBox3.Color); form.Colors = colors; if(form.ShowDialog() == DialogResult.OK) { userControlImage1.ReplaceColor(form.BeforeColor, form.AfterColor, form.IsBeforeColorTransparent, form.IsAfterColorTransparent, form.differenceR, form.differenceG, form.differenceB); } form.Dispose(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public partial class Form1 : Form { private void SelectionColorReplaceMenuItem_Click(object sender, EventArgs e) { if(userControlImage1.Bitmap == null) { MessageBox.Show("画像が読み込まれていません", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if(!userControlImage1.IsSelected()) { MessageBox.Show("範囲選択されていません", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } ColorReplaceForm form = new ColorReplaceForm(); form.Text = "色の置換(選択されている部分のみ)"; List<Color> colors = new List<Color>(); if(userControlColorBox1.Color != Color.Empty) colors.Add(userControlColorBox1.Color); if(userControlColorBox2.Color != Color.Empty) colors.Add(userControlColorBox2.Color); if(userControlColorBox3.Color != Color.Empty) colors.Add(userControlColorBox3.Color); form.Colors = colors; if(form.ShowDialog() == DialogResult.OK) { userControlImage1.ReplaceColorInRectangle( form.BeforeColor, form.AfterColor, form.IsBeforeColorTransparent, form.IsAfterColorTransparent, form.differenceR, form.differenceG, form.differenceB); } form.Dispose(); } } |