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

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

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

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

Q&A

解決済

2回答

911閲覧

選択した7色の組み合わせの画像を127通り作りたいです。

setun

総合スコア1

C#

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

1グッド

1クリップ

投稿2021/08/30 00:33

前提・実現したいこと

visual studio2019を使用しc#を使ってプログラムを作成しています(C#は初心者です)。form画面で色を選択するボタンを7個設置してそれぞれカラーダイアログに繋げており、出力ボタンを押すとフォルダに1~7色を使用した組み合わせが重複しない画像127個を出力するプログラムがなかなかできません。また、ファイル名を使用した色にあわせるようにしたいです。コードを記入しますので助言のほどよろしくお願いいたします。

発生している問題・エラーメッセージ

ファイルが実現したいようにできない、127通りの画像を出力できない。

該当のソースコード

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Drawing.Imaging; using System.Diagnostics; using static System.Console; using System.Text.RegularExpressions; namespace WindowsFormsApp1 { public partial class PLTIG : Form { public PLTIG() { InitializeComponent(); } /// <summary> /// 初期ロード /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { this.Text = "PlayListTypeImageGenerator"; FrNm.Text = Properties.Settings.Default.FrNm; Gl1.BackColor = Properties.Settings.Default.P1; PG1.BackColor = Properties.Settings.Default.P2; PR1.BackColor = Properties.Settings.Default.P3; ETY1.BackColor = Properties.Settings.Default.P4; ETMR1.BackColor = Properties.Settings.Default.P5; ETWR1.BackColor = Properties.Settings.Default.P6; EThR1.BackColor = Properties.Settings.Default.P7; Rectwidth.Text = Properties.Settings.Default.width; Rectheight.Text = Properties.Settings.Default.height; } private void FDS_Click(object sender, EventArgs e) { DialogResult dr = folderBrowserDialog1.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { FrNm.Text = folderBrowserDialog1.SelectedPath; FrNm.ReadOnly = true; } } private void btnCC_Click(object sender, EventArgs e) { DialogResult dr = colorDialog1.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { Gl1.BackColor = colorDialog1.Color; G.ReadOnly = true; } } private void textBox1_TextChanged(object sender, EventArgs e) { } private void btnCC2_Click(object sender, EventArgs e) { DialogResult dr = colorDialog2.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { PG1.BackColor = colorDialog2.Color; PGl.ReadOnly = true; } } private void btnCC3_Click(object sender, EventArgs e) { DialogResult dr = colorDialog3.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { PR1.BackColor = colorDialog3.Color; PRe.ReadOnly = true; } } private void btnCC4_Click(object sender, EventArgs e) { DialogResult dr = colorDialog4.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { ETY1.BackColor = colorDialog4.Color; ETYRe.ReadOnly = true; } } private void btnCC5_Click(object sender, EventArgs e) { DialogResult dr = colorDialog5.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { ETMR1.BackColor = colorDialog5.Color; ETMRe.ReadOnly = true; } } private void btnCC6_Click(object sender, EventArgs e) { DialogResult dr = colorDialog6.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { ETWR1.BackColor = colorDialog6.Color; ETWRe.ReadOnly = true; } } private void btnCC7_Click(object sender, EventArgs e) { DialogResult dr = colorDialog7.ShowDialog(); if (dr == System.Windows.Forms.DialogResult.OK) { EThR1.BackColor = colorDialog7.Color; EThRe.ReadOnly = true; } } /// <summary> /// 重複しない組み合わせを作るための関数 /// </summary> public static class Combination { public static IEnumerable<T[]> Enumerate<T>(IEnumerable<T> items,int k ,bool withRepetition) { if (k == 1) { foreach (var item in items) yield return new T[] { item }; yield break; } foreach (var item in items) { var leftside = new T[] { item }; // item よりも前のものを除く (順列と組み合わせの違い) // 重複を許さないので、unusedから item そのものも取り除く var unused = withRepetition ? items : items.SkipWhile(e => !e.Equals(item)).Skip(1).ToList(); var list = Enumerate(unused, k-1 , withRepetition); foreach (var rightside in list) { yield return leftside.Concat(rightside).ToArray(); } } } } public void SaveControlImage( string file) { //描画先とするImageオブジェクトを作成する using (var canvas = new Bitmap((int)Rectwidth.Value, (int)Rectheight.Value)) { float w = (float)Rectwidth.Value; float h = (float)Rectheight.Value; //ImageオブジェクトのGraphicsオブジェクトを作成する var g = Graphics.FromImage(canvas); //Brushオブジェクトの作成 SolidBrush f = new SolidBrush(Gl1.BackColor); SolidBrush se = new SolidBrush(PG1.BackColor); SolidBrush th = new SolidBrush(PR1.BackColor); SolidBrush fr = new SolidBrush(ETY1.BackColor); SolidBrush fif = new SolidBrush(ETMR1.BackColor); SolidBrush sixth = new SolidBrush(ETWR1.BackColor); SolidBrush sevth = new SolidBrush(EThR1.BackColor); var Crck = new List<SolidBrush>(); Crck.Add(f); Crck.Add(se); Crck.Add(th); Crck.Add(fr); Crck.Add(fif); Crck.Add(sixth); Crck.Add(sevth); var CrCom = new Dictionary<SolidBrush, string>(); CrCom.Add(f, "Gl"); CrCom.Add(se, "PG"); CrCom.Add(th, "PR"); CrCom.Add(fr, "ETY"); CrCom.Add(fif, "ETMR"); CrCom.Add(sixth, "ETWR"); CrCom.Add(sevth, "EThR"); int n = 7; for (int k = 1; k < n + 1; k++) { var combinations = Combination.Enumerate(Crck, k, withRepetition: false); foreach ( var elem in combinations) { for (int j = 0; j < elem.Count(); j++) { g.FillRectangle(elem[j], j * (w/k) , 0, w / (j+1), h); } canvas.Save(file, System.Drawing.Imaging.ImageFormat.Png); } } f.Dispose(); se.Dispose(); th.Dispose(); fr.Dispose(); fif.Dispose(); sixth.Dispose(); sevth.Dispose(); g.Dispose(); } } public void Output_Click(object sender, EventArgs e) { int i = 1; while (i < 128) { var di = new DirectoryInfo(Environment.CurrentDirectory); var tagName = ""; var max = di.GetFiles(tagName + "_???.txt") // パターンに一致するファイルを取得する .Select(fi => Regex.Match(fi.Name, @"(?i)_(\d{3}).txt$")) // ファイルの中で数値のものを探す .Where(m => m.Success) // 該当するファイルだけに絞り込む .Select(m => Int32.Parse(m.Groups[1].Value)) // 数値を取得する .DefaultIfEmpty(0) // 1つも該当しなかった場合は 0 とする .Max(); // 最大値を取得する var fileName = String.Format("{0}_{1:d3}.png", tagName, max + 1); SaveControlImage(Path.Combine(FrNm.Text, fileName)); i++; } }

試したこと

組み合わせを重複しないプログラムの作成
ファイル名を組み合わせた色にあわせるようにdictionaryを使って作れないか摸索

補足情報(FW/ツールのバージョンなど)

visual studio2019。

TN8001👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/08/30 01:03 編集

・プロジェクトの種類(Windowsフォームアプリ、WPFアプリ、ASP.NET Webアプリ等) ・フレームワークのバージョン(.NET Framework X.X、.NET Core X.X等) を質問を編集して追記してください。 具体的に何が判らなくて作れないんですか?コードだけ見てあなたの判らない点を知るのは無理(判るとしても、時間の無駄)なので、技術的に解決できない点、どういうインプットに対してどういうアウトプットになるか等、具体的に説明してください。 [2. 質問をする前に自分で何がわからないのかを把握しましょう] https://teratail.com/help/question-tips#questionTips2
fana

2021/08/30 02:21 編集

> ファイル名を使用した色にあわせる とか言われても,具体的にどういう名前を付ければいいのかさっぱりわからない. (任意の色の名前をどうやって表すのか?) 7色使うやつとかだとめちゃくちゃ長いファイル名になる?
dodox86

2021/08/30 01:40

1~7色を使用した組み合わせが重複しない127個の組み合わせとはどのようなものなのでしょう。 [[1], [2], [3], [4], [5], [6], [7]]で7個、[[1,2], [1,3], [1.4], [1,5], [1,6], [1,7]]で6個、合計13個、、、、(以下続く) とか、組み合わせの仕方を決めてそれを実装する必要があると思いますがその辺りはできているのでしょうか。
dodox86

2021/08/30 01:43

ひとつの方法として7ビットのビットマップで1~127まで回せば自然、できてしまう気もしますが。
guest

回答2

0

ベストアンサー

参考コードがある場合は出典を質問に明示してください。
C#:n個の要素からk個を選ぶ組合せを列挙する - Qiita

7色の組み合わせの画像を127通り作りたい

7個中から1個選ぶ重複しない組合せ:7
7個中から2個選ぶ重複しない組合せ:21
7個中から3個選ぶ重複しない組合せ:35
7個中から4個選ぶ重複しない組合せ:35
7個中から5個選ぶ重複しない組合せ:21
7個中から6個選ぶ重複しない組合せ:7
7個中から7個選ぶ重複しない組合せ:1
計:127通りということですね。そしてそれはもうできている。と

ファイルが実現したいようにできない、127通りの画像を出力できない。

Output_Clickがどういう意図か1ミリもわからないのですが、canvas.Saveでpngファイルを作るのだから都度ファイル名を変えないといけないのでは?

ファイル名を組み合わせた色にあわせるようにdictionaryを使って作れないか摸索

皆さんおっしゃっていますが、setunさんがどういうファイル名にしたいのかがまったく伝わっていません。

ColorDialogは1個で十分です。使いまわせるのでボタン分作る必要はありません。

全体的に変数名がひどすぎます。ButtonなのかLabelなのかTextBoxなのかまったくわかりません。
ひとりで作っているならどうでもいいですが、第三者に見せるのなら、わかりやすい名前に変える・説明をつける・Designer.csを提示する等の配慮が必要です。

やりたいこと自体は分かったので、3色版を書いてみました。

cs

1using System; 2using System.Collections.Generic; 3using System.Data; 4using System.Drawing; 5using System.Drawing.Imaging; 6using System.Linq; 7using System.Windows.Forms; 8 9namespace Questions356810 10{ 11 public partial class Form1 : Form 12 { 13 public Form1() 14 { 15 InitializeComponent(); 16 //color1Button.BackColor = Color.Red; 17 //color2Button.BackColor = Color.Lime; 18 //color3Button.BackColor = Color.Blue; 19 } 20 21 private void Color1Button_Click(object sender, EventArgs e) 22 { 23 if (colorDialog1.ShowDialog() == DialogResult.OK) 24 color1Button.BackColor = colorDialog1.Color; 25 } 26 private void Color2Button_Click(object sender, EventArgs e) 27 { 28 if (colorDialog1.ShowDialog() == DialogResult.OK) 29 color2Button.BackColor = colorDialog1.Color; 30 } 31 private void Color3Button_Click(object sender, EventArgs e) 32 { 33 if (colorDialog1.ShowDialog() == DialogResult.OK) 34 color3Button.BackColor = colorDialog1.Color; 35 } 36 37 private void OutputButton_Click(object sender, EventArgs e) 38 { 39 float w = 100; 40 float h = 100; 41 42 using (var canvas = new Bitmap((int)w, (int)h)) 43 using (var graphics = Graphics.FromImage(canvas)) 44 using (var brush1 = new SolidBrush(color1Button.BackColor)) 45 using (var brush2 = new SolidBrush(color2Button.BackColor)) 46 using (var brush3 = new SolidBrush(color3Button.BackColor)) 47 { 48 // Combination.EnumerateはDictionaryでも使える 49 // 文字列との対応を取りたいのであればこれを渡せばいい 50 var choices = new Dictionary<string, SolidBrush> 51 { 52 { "Color1", brush1 }, 53 { "Color2", brush2 }, 54 { "Color3", brush3 }, 55 }; 56 57 var count = 1; 58 for (var i = 1; i <= choices.Count; i++) 59 { 60 var combinations = Combination.Enumerate(choices, i, false); 61 foreach (var combination in combinations) 62 { 63 for (var j = 0; j < combination.Length; j++) 64 { 65 var brush = combination[j].Value; 66 graphics.FillRectangle(brush, w / i * j, 0, w / i, h); 67 } 68 69 var keys = string.Join("-", combination.Select(x => x.Key)); 70 var codes = string.Join("-", combination.Select(x => x.Value.Color) 71 .Select(x => $"#{x.R:X2}{x.G:X2}{x.B:X2}")); 72 73 var fileName = $"{count}_{keys}_{codes}.png"; 74 canvas.Save(fileName, ImageFormat.Png); 75 count++; 76 } 77 } 78 } 79 } 80 } 81 82 83 // [C#:n個の要素からk個を選ぶ組合せを列挙する - Qiita](https://qiita.com/gushwell/items/74a96f56ccb64db3660c) 84 static class Combination 85 { 86 public static IEnumerable<T[]> Enumerate<T>(IEnumerable<T> items, int k, bool withRepetition) 87 { 88 if (k == 1) 89 { 90 foreach (var item in items) yield return new T[] { item }; 91 yield break; 92 } 93 foreach (var item in items) 94 { 95 var leftside = new T[] { item }; 96 var unused = withRepetition ? items : items.SkipWhile(e => !e.Equals(item)).Skip(1).ToList(); 97 foreach (var rightside in Enumerate(unused, k - 1, withRepetition)) 98 yield return leftside.Concat(rightside).ToArray(); 99 } 100 } 101 } 102}

出力ファイル

投稿2021/08/30 10:06

編集2023/07/28 17:20
TN8001

総合スコア9326

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

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

setun

2021/08/31 01:54

ありがとうございました。注意された箇所も今後直していけるように頑張ります。
guest

0

たとえば、色が3つの場合のすべての組み合わせ(8通り)を出すなら、

for( int i=0;i<0x8;i++){
if(i&1) 色1
if(i&2) 色2
if(i&4) 色3
}

でだせます。
これを7つにすればいいというはなしになりますね

投稿2021/08/30 02:03

y_waiwai

総合スコア87784

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問