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");
    }
}

 

*1:@"./a.txt"

*2:@"./a.txt"

*3:@"./a.txt"

*4:@"./a.txt"

*5:@"./a.txt"