画像フォーマットPPM その3

chakemiです。

本日はPPMファイルをダンプしてBMPファイルに書き出してみました。

開発環境

  • Windows7
  • VisualStudio2010Express

今回は、処理がめんどくさかったので、バイナリ形式(P6)のファイルのみを対象としました。 また、コメント行を保持した24bitカラーのファイルのみ処理するようにしました。

単純に上から順に読み込んで処理をするだけですが、まぁ素人なんでこんなもんでしょ。

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.IO;
using System.Collections;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace PpmTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int readSize;
            byte[] P = new byte[2];
            byte[] lf = new byte[1];
            string line="";
            long fPos;

            FileStream fs = new FileStream(args[0], FileMode.Open, FileAccess.Read);

            readSize = fs.Read(P, 0, P.Length);
            string bufString = Encoding.UTF8.GetString(P);
            if (bufString != "P6")
            {
                Console.WriteLine("PPMファイルがバイナリ形式ではありません");
                fs.Dispose();
                return;
            }

            //改行コード読み飛ばし
            readSize = fs.Read(lf, 0, lf.Length);
            bufString = Encoding.UTF8.GetString(lf);
            fPos = fs.Position;


            StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("UTF-8"));
            line = sr.ReadLine();
            if(line.Substring(0,1) != "#")
            {
                //コメント行のないファイルは対象外
                Console.WriteLine("対象外ファイルです");
                fs.Dispose();
                return;
            }
            Console.WriteLine(line);
            fs.Seek(line.Length +fPos, SeekOrigin.Begin);


            //改行コード読み飛ばし
            readSize = fs.Read(lf, 0, lf.Length);
            bufString = Encoding.UTF8.GetString(lf);
            fPos = fs.Position;

            //横・縦サイズ取得
            line = sr.ReadLine();
            Console.WriteLine(line);

            string[] size = line.Split(new char[]{' '});
            int x = int.Parse(size[0]);
            int y = int.Parse(size[1]);
            fs.Seek(line.Length+fPos, SeekOrigin.Begin);

            //改行コード読み飛ばし
            readSize = fs.Read(lf, 0, lf.Length);
            bufString = Encoding.UTF8.GetString(lf);
            fPos = fs.Position;

            line = sr.ReadLine();
            Console.WriteLine(line);
            if (line != "255")
            {
                Console.WriteLine("24bitカラーではありません");
                fs.Dispose();
                return;
            }
            fs.Seek(line.Length+fPos, SeekOrigin.Begin);

            //改行コード読み飛ばし
            readSize = fs.Read(lf, 0, lf.Length);
            bufString = Encoding.UTF8.GetString(lf);


            byte[,] datar = new byte[x, y];
            byte[,] datag = new byte[x, y];
            byte[,] datab = new byte[x, y];


            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    datar[j, i] = (Byte)fs.ReadByte();
                    datag[j, i] = (Byte)fs.ReadByte();
                    datab[j, i] = (Byte)fs.ReadByte();
                }
            }

            Bitmap bitmap = new Bitmap(x, y, PixelFormat.Format24bppRgb);
            int[,] r = new int[x, y];
            int[,] g = new int[x, y];
            int[,] b = new int[x, y];


            for (int yy = 0; yy < y; yy++)
            {
                for (int xx = 0; xx < x; xx++)
                {
                    r[xx, yy] = ((int)datar[xx, yy]);
                    g[xx, yy] = ((int)datag[xx, yy]);
                    b[xx, yy] = ((int)datab[xx, yy]);

                    bitmap.SetPixel(xx, yy,
                    Color.FromArgb(
                    r[xx, yy],
                    g[xx, yy],
                    b[xx, yy]
                    ));

                }
            }

            Console.WriteLine("complete");
            bitmap.Save("outbmp.bmp");
        }
    }
}

とりあえず、変換したビットマップ

うん、とりあえず、ちゃんと確認したから大丈夫なはず。

ヘッダが単純すぎて、逆に不定な値をどうとったらお洒落か考えているうちに時間なくなっちゃって、 若干、怪しい部分もありますが、引き続き勉強のためにちゃんと書き直そうと思います。