PGM画像の簡単な編集ソフトを作りました
簡単なPGM画像を編集するソフト
↓
→
テキストファイルを上から1行ずつ読み込むには
StreamReader sr = new StreamReader(@"C:\Users\username\Desktop\c#\画像編集\あ.txt");
while (0 <= sr.Peek())
{
str[count] = sr.ReadLine();
if (count >= 3)
{
str[count] += "E";//Eは改行記号の代わり
}
count++;
}
テキストファイル : sr
sr.Peek()は読み取り対象に文字があったら-1以外を返す
この場合は、次の行に何も書いてなかったら-1を返す
str[count] = sr.ReadLine(); これでstr[count]にテキストファイルの一行を入れます
PGM形式では、書式が決まっているのでstrを配列にすることで、特定の情報を得たいときに、countを指定することで、取得できます。
例えば:ファイル形式が欲しい→count=0 a = str[count]のように
範囲を読み取り、数値として使用できるようにする
count = 1;
leng = str[count].Length;
for (int i = 0; i < leng; i++)
{
mozi[i] = str[count][i];
}
char tate1 = new char { mozi[0], mozi[1] };
char yoko2 = new char { mozi[3], mozi[4] };
string tate1s = new string(tate1);
string yoko2s = new string(yoko2);
string[,] suuzi = new string[tate,yoko];
int[,] suuzi_int = new int[tate, yoko];
今のところ 二けた×二けた しか対応できていません
for (int i = 0; i < leng; i++)
{
mozi[i] = str[count][i];
}
count = 1、これで二行目を指定します。mozi[i]に一文字ずつ入れてます。
そして、char tate1 = new char { mozi[0], mozi[1] };で1と0をcharの配列に入れています。
そしてstring tate1s = new string(tate1);で1と0を一つのstring型として記録しています
横の範囲の数値も同様にやっています。
これらをすることで、後のループの制御に使用しています。
画像を構成する数値を読み取る
string[,] suuzi = new string[tate,yoko];
int[,] suuzi_int = new int[tate, yoko];
int tate_count = 0;
int yoko_count = 0;
string hikae;
int g = 0;
count = 3;
while(count < tate + 3)
{
while(yoko_count != yoko)
{
hikae = str[count][g].ToString();
if (hikae != " ")
{
suuzi[tate_count,yoko_count] = hikae;
g++;
while (true)
{
hikae = str[count][g].ToString();
if(hikae == "E")
{
break;
}
if(hikae != " ")
{
suuzi[tate_count,yoko_count] += hikae;
f++;
g++;
}
else
{
break;
}
}
}
g++;
yoko_count++;
}
count++;
tate_count++;
g = 0;
yoko_count = 0;
}
string[,] suuzi = new string[tate,yoko];で縦横分の要素を持てる変数を用意する
int[,] suuzi_int = new int[tate, yoko];で読み取った数値を保存します。
int[tate, yoko]とすることで、自分がテキストファイルの数字を、
縦2番目の、横2番目の数字が1と認識するように、配列でもint[2,2]には1が入るようになるので、わかりやすくなります。
int tate_count = 0;
int yoko_count = 0;
string hikae;
int g = 0;
count = 3;
tate_count : int[,]の要素の中からの縦○列目を指定する tate_count =1 だと縦1列目
yoko_count : int[,]の横○列目のを横○列目を指定する yoko_count = 1 だと横1列目
string hikaeで一応、配列変数から文字を写すように使っていましたが、たぶんいらない
int g = 0;gはstr[count]に入っている1文の何番目かを指定する
str[count][g] g=2でstr[count]の3文字目を取得する。
count = 3 はstr[count]の画像を構成する部分のみを取得するためのもの
count が tate+3 とは異なればループ +3は3行、ループとは関係ない行があるから
しかし、str[count]には1行目からの関係のない行も含まれるから。
+3しないと10 10 でも7行分しか取得できない
yoko_count とyokoと異なればループ
yoko_count とyokoと等しくなるのは、最後の文字を取得した後、yoko_count++;により
yoko と等しくなる
hikae = str[count][g].ToString();
if (hikae != " ")
{
suuzi[tate_count,yoko_count] = hikae;
g++;
while (true)
{
hikae = str[count][g].ToString();
if(hikae == "E")
{
break;
}
if(hikae != " ")
{
suuzi[tate_count,yoko_count] += hikae;
f++;
g++;
}
else
{
break;
}
}
}
hikae = str[count][g].ToString();で指定した行の文字を取得する
if (hikae != " ")
{
suuzi[tate_count,yoko_count] = hikae;
g++;
取得したのがスペースでなければその数字をsuuzi[,]に記録する
g++;で次に取得する文字を1つ右にずらす
while (true)
{
hikae = str[count][g].ToString();
if(hikae == "E")
{
break;
}
if(hikae != " ")
{
suuzi[tate_count,yoko_count] += hikae;
f++;
g++;
}
else
{
break;
}
hikae = str[count][g].ToString();
if(hikae == "E")
{
break;
}
再びhuikaeに文字を入れる、そしてEは1文の最後につけられてるので、Eは改行を表しています。Eが出る、つまり改行されて、文の終わりだったら、ループを抜ける
if(hikae != " ")
{
suuzi[tate_count,yoko_count] += hikae;
g++;
} else
{
break;
}
もしhikaeがスペースでなければ先ほどと同じsuuzi[,]にhikaeを付け加えます
例 hikae = 1 → suuzi[0,0] =1 → hikae= 0 → suuzi[0,0] =10
このようにhikaeの中身がスペースになるまで繰り返します
g++;
yoko_count++;
g++;で次に取得する文字を1つ右にずらす
yoko_count++;で取得した文字を入れるsuuzi[,]を変える
count++;
tate_count++;
g = 0;
yoko_count = 0;
count++;でテキストファイルから1行下を指定する
tate_count++;で取得した文字を入れるsuuzi[,]をずらす
g = 0;右に1文字ずつ読み込むためにずらしていたので0に戻してまた右からは読み込み始める
yoko_count = 0;suuzi[,]における横の列をリセットする
for (int i = 0; i < tate; i++)
{
for (int j = 0; j < yoko; j++)
{
suuzi_int[i, j] = int.Parse(suuzi[i, j]);
suuzi_int[i, j] = 255 - suuzi_int[i, j];
}
}
suuzi[,]の中身をすべてint型にして、その数字に任意の操作をする
string yoko_str = new string[yoko * 2];
for (count = 0; count < tate; count++)
{
for (int j = 0; j < yoko; j++)
{
yoko_str[count] += suuzi_int[count, j].ToString();
if (j != yoko - 1)
{
yoko_str[count] += " ";
}
}
}
string yoko_str = new string[yoko * 2];
この変数に、テキストファイルに書き込む数値やスペースを入れます
for (int j = 0; j < yoko; j++)
{
yoko_str[count] += suuzi_int[count, j].ToString();
if (j != yoko - 1)
{
yoko_str[count] += " ";
}
}
j < yoko は横に指定した文字数だけ(10 10の場合 10回)繰り返す
yoko_str[count] += suuzi_int[count, j].ToString();
yoko_str[count]にchar型のsuuzi_int[count]を.Tostring()でstring型にして
yoko_str[count]に数値を入れる
if (j != yoko - 1)
{
yoko_str[count] += " ";
}
yoko_str[count]に数字を加えたら、テキストファイルに書き込むとき、数字の隣にスペースを書くために、yoko_str[count]にスペースを加える
string stra = System.IO.Directory.GetCurrentDirectory();
string textfile = Directory.GetFiles(stra);
bool filecheck = false;
int fcount = 0;
foreach (string tex in textfile)
{
string file_name = Path.GetFileName(tex);
if (file_name == "a.pgm")
{
filecheck = true;
fcount = 1;
text = tex;
}
}
string stra = System.IO.Directory.GetCurrentDirectory();
exeファイルのあるフォルダのパスを取得しています
string textfile = Directory.GetFiles(stra);
そのフォルダの中にあるファイルのパスを取得します
bool filecheck = false;
int fcount = 0;
foreach (string tex in textfile)
{
string file_name = Path.GetFileName(tex);
if (file_name == "a.pgm")
{
filecheck = true;
fcount = 1;
text = tex;
}
}
foreach(string tex in textfile)で記録したファイルのパスがある分だけ繰り返す
そのファイルの名前をstring file_name = Path.GetFileName(tex);でfile_nameに記録します。
if (file_name == "a.pgm")
{
filecheck = true;
fcount = 1;
text = tex;
}
これで、指定したファイルがあれば、filecheckをtrueにして、そのファイルを消す
StreamWriter writer;
if (!filecheck)
{
FileStream fs = File.Create*1;
writer = new StreamWriter(fs);
}
else
{
File.Delete(@text);
FileStream fs = File.Create*2;
writer = new StreamWriter(fs);
}
先ほどのように、もし指定したファイルがあったらそれを削除する
FileStream fs = File.Create*3;
writer = new StreamWriter(fs);
指定した名前のファイルを作成して、それにアクセスできるようにする
writer.WriteLine("P2");
writer.WriteLine(str[1]);
writer.WriteLine("255");
for (int i = 0; i < tate; i++)
{
writer.WriteLine(yoko_str[i]);
}
writer.Close();
System.IO.File.Move(@"./a.txt", @"./a.pgm");
}
PGM形式に必要なものを書き込んでゆく
writer.Close()で書き込みを終了する。これがないと書き込めない
System.IO.File.Move(@"./a.txt", @"./a.pgm");で.txtから.pgmにして、作成したファイルの形式をテキスト形式からPGM形式に変える。
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
class Program
{
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
class Form1 : Form
{
Label l = new Label[100];
string str = new string[100];
char mozi = new char[10];
int leng;
bool P2 = false;
int youso = new int[1000];
string text;
public Form1()
{
this.Text = "Title";
this.StartPosition = FormStartPosition.Manual; // 位置の決定方法
this.Location = new Point(100, 50); // ウィンドウの位置
this.Size = new Size(500, 500);
StreamReader sr = new StreamReader(@"C:\Users\username\Desktop\c#\画像編集\あ.txt");
int count = 0;
while (0 <= sr.Peek())
{
str[count] = sr.ReadLine();
if (count >= 3)
{
str[count] += "E";//Eは改行記号の代わり
}
count++;
}
while (count >= 0)
{
l[count] = new Label()
{
Text = str[count],
Location = new Point(0, 30 * count),
};
this.Controls.Add(l[count]);
count--;
}
count = 1;
leng = str[count].Length;
for (int i = 0; i < leng; i++)
{
mozi[i] = str[count][i];
}
if (str[0] == "P2")
{
P2 = true;
}
char tate1 = new char { mozi[0], mozi[1] };
char yoko2 = new char { mozi[3], mozi[4] };
string tate1s = new string(tate1);
string yoko2s = new string(yoko2);
int tate = int.Parse(tate1s);
int yoko = int.Parse(yoko2s);
string[,] suuzi = new string[tate,yoko];
int[,] suuzi_int = new int[tate, yoko];
int tate_count = 0;
int yoko_count = 0;
string hikae;
int g = 0;
count = 3;
while(count < tate + 3)
{
while(yoko_count != yoko)
{
hikae = str[count][g].ToString();
if (hikae != " ")
{
suuzi[tate_count,yoko_count] = hikae;
g++;
while (true)
{
hikae = str[count][g].ToString();
if(hikae == "E")
{
break;
}
if(hikae != " ")
{
suuzi[tate_count,yoko_count] += hikae;
f++;
g++;
}
else
{
break;
}
}
}
g++;
yoko_count++;
}
count++;
tate_count++;
g = 0;
yoko_count = 0;
}
for (int i = 0; i < tate; i++)
{
for (int j = 0; j < yoko; j++)
{
suuzi_int[i, j] = int.Parse(suuzi[i, j]);
suuzi_int[i, j] = 255 - suuzi_int[i, j];
}
}
string yoko_str = new string[yoko * 2];
for (count = 0; count < tate; count++)
{
for (int j = 0; j < yoko; j++)
{
yoko_str[count] += suuzi_int[count, j].ToString();
if (j != yoko - 1)
{
yoko_str[count] += " ";
}
}
}
string stra = System.IO.Directory.GetCurrentDirectory();
string textfile = Directory.GetFiles(stra);
bool filecheck = false;
int fcount = 0;
foreach (string tex in textfile)
{
string file_name = Path.GetFileName(tex);
if (file_name == "a.pgm")
{
filecheck = true;
fcount = 1;
text = tex;
}
}
StreamWriter writer;
if (!filecheck)
{
FileStream fs = File.Create*4;
writer = new StreamWriter(fs);
}
else
{
File.Delete(@text);
FileStream fs = File.Create*5;
writer = new StreamWriter(fs);
}
writer.WriteLine("P2");
writer.WriteLine(str[1]);
writer.WriteLine("255");
for (int i = 0; i < tate; i++)
{
writer.WriteLine(yoko_str[i]);
}
writer.Close();
System.IO.File.Move(@"./a.txt", @"./a.pgm");
}
}