【C#】csvのデータをpicture boxに画像表示する

エンジニアの方向けです。
評価で取ったcsvデータを画像表示したいことってありませんか?
C#で、csvデータを画像に起こして、picture boxに表示させてみたいと思います。

やること
・csvデータを読み込む
・画像用の値に変換する
・picture boxに表示する
・(おまけ)pixture boxに合わせて画像をリサイズする

それでは順番に見ていきましょう!

目次

順番に見ていく

csvデータをリストに読み込む

実行ファイルと同じ階層にある「sample.csv」を読んで、Listの入れ子に取り込みます。
csvファイルはカンマ区切りを想定しています。
ゴミデータ

string filename = "sample.csv";
List<List<double>> datas = new List<List<double>>();
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
string[] lines = System.IO.File.ReadAllLines(filename, enc);
foreach (string s in lines)
{
    List<double> tmp_d = new List<double>();
    List<string> tmp_str = s.Split(',').ToList();
    foreach (string ss in tmp_str)
    {tmp_d.Add(Convert.ToDouble(ss));}
    datas.Add(tmp_d);
}

画像用の値に変換する

picture boxに表示する画像データは8bit(256階調)です。
RGBそれぞれ8bitで指定できますが、今回はモノクロでやってみます。
下記では、元データを12bitで想定して、8bitに正規化しています。

int col_num = datas[0].Count();
int row_num = datas.Count();
Bitmap bmp = new Bitmap(col_num, row_num);//width, height, bitmapの入れ物作成

double max = 4096;
int cnt_row = 0;
foreach (List<double> list_d in datas)
{
    int cnt_col = 0;
    foreach (double d in list_d)
    {
        int tmp = (int)(d / max * 255);
        if (tmp > 255) { tmp = 255; }//例外処理
        if (tmp < 0) { tmp = 0; };//例外処理
        int red = tmp;
        int green = tmp;
        int blue = tmp;
        Color newColor = Color.FromArgb(255, red, green, blue);//α値255
        bmp.SetPixel(cnt_col, cnt_row, newColor);
        cnt_col += 1;
    }
    cnt_row += 1;
}

picture boxに表示する

pictureBox1.Image = bmp;

とてもシンプルですね。先ほど作成した画像データをpicture boxに表示します。

(おまけ)pixture boxに合わせて画像をリサイズする

string bmppath = "bmp.bmp";
bmp.Save(bmppath, ImageFormat.Bmp);

//ピクチャーボックスの画像を拡大縮小
Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(canvas);
Image img = Image.FromFile(bmppath); // 元の画像
// 縮小・拡大のモード(補間方法)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
float scale_w = (float)pictureBox1.Width / (float)img.Width;
float scale_h = (float)pictureBox1.Height / (float)img.Height;
float scale_i;
if (scale_w > scale_h) { scale_i = scale_h; }
else { scale_i = scale_w; }

g.DrawImage(img, 0, 0, img.Width * scale_i, img.Height * scale_i);

pictureBox1.Image = canvas;
img.Dispose(); g.Dispose();

元データのピクセル数が多かったり少なかったりすると、picture boxにうまく表示されないことがあります。
そこで、picture boxのサイズに合わせてリサイズします。
用途によって、補間して潰れて欲しくない時、リサイズして見たい時両方あると思います。
サンプルでは次の両方をしています。
・元のサイズの画像をファイル出力する(補間していない生画像データ)
・picture boxにリサイズした画像を表示する(補間して見やすくしたデータ)

サンプルコード

上記で説明したものを合体したのがこちらです。

string filename = "sample.csv";
List<List<double>> datas = new List<List<double>>();
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
string[] lines = System.IO.File.ReadAllLines(filename, enc);
foreach (string s in lines)
{
    List<double> tmp_d = new List<double>();
    List<string> tmp_str = s.Split(',').ToList();
    foreach (string ss in tmp_str)
    {tmp_d.Add(Convert.ToDouble(ss));}
    datas.Add(tmp_d);
}

int col_num = datas[0].Count();
int row_num = datas.Count();
Bitmap bmp = new Bitmap(col_num, row_num);//width, height, bitmapの入れ物作成

double max = 4096;
int cnt_row = 0;
foreach (List<double> list_d in datas)
{
    int cnt_col = 0;
    foreach (double d in list_d)
    {
        int tmp = (int)(d / max * 255);
        if (tmp > 255) { tmp = 255; }//例外処理
        if (tmp < 0) { tmp = 0; };//例外処理
        int red = tmp;
        int green = tmp;
        int blue = tmp;
        Color newColor = Color.FromArgb(255, red, green, blue);//α値255
        bmp.SetPixel(cnt_col, cnt_row, newColor);
        cnt_col += 1;
    }
    cnt_row += 1;
}
pictureBox1.Image = bmp;
string bmppath = "bmp.bmp";
bmp.Save(bmppath, ImageFormat.Bmp);

//ピクチャーボックスの画像を拡大縮小
Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(canvas);
Image img = Image.FromFile(bmppath); // 元の画像
// 縮小・拡大のモード(補間方法)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
float scale_w = (float)pictureBox1.Width / (float)img.Width;
float scale_h = (float)pictureBox1.Height / (float)img.Height;
float scale_i;
if (scale_w > scale_h) { scale_i = scale_h; }
else { scale_i = scale_w; }

g.DrawImage(img, 0, 0, img.Width * scale_i, img.Height * scale_i);

pictureBox1.Image = canvas;
img.Dispose(); g.Dispose();

以上です。
誰かのお役に立てば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次