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

このエントリーをはてなブックマークに追加

chakemiです。風邪がまったく治りません。。。
更新が遅くなってしまいましたが、本日はPPMファイルをダンプして
BMPファイルに書き出してみました。

開発環境:
Windows7
VisualStudio2010Express

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

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

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

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

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

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

return top