PNM(portable anymap ファイルフォーマット)

PNM(portable anymap ファイルフォーマット)はpbm(portable bitmap), pgm(portable graymap), ppm(portable pixmap)の各画像フォーマットを総称した名前です。 PNMのファイル形式はテキスト/バイナリ形式を選択することにより、メモ帳等でも簡単に編集することが可能です。

その形式には以下の6種類があります。
P1 (PBM) 2値画像  テキスト形式 
P2 (PGM) 濃淡画像  テキスト形式 
P3 (PPM) カラー画像  テキスト形式 
P4 (PBM) 2値画像  バイナリ形式 
P5 (PGM) 濃淡画像  バイナリ形式 
P6 (PPM) カラー画像  バイナリ形式 

P4?P6の形式では画像のヘッダ部分を除いた画像データ部をバイナリ形式で出力しなければならないので、メモ帳等での編集は無理ですが、P1?P3の形式はテキスト形式で画像の輝度・色情報(R,G,B)を書き込めますので、メモ帳等で簡単に編集することが可能です。

ファイルフォーマットは以下のようなものです。

 Pn          |              → 画像識別子: P1?P6
 5 5         +--- ヘッダ部  → 横幅 縦幅
 5           |              → 最大輝度値(PBMでは必要ない)
 0 1 0 1 0      |
 0 1 0 1 0      |
 0 1 0 1 0      +---画像データ部(PBM,PGMの場合)
 0 1 0 1 0      |              (PPMでは R,G,B の順に記述)
 0 1 0 1 0      |

 画像例

実際の画像の記述の例と、記述により得られた画像の例です。

PBM形式
P1
10 10
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 1 0
PGM形式
P2
11 11
255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
0 25 50 75 100 125 150 175 200 225 255
PGM形式
P3
9 9
255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255 255 0 0 0 255 0 0 0 255

 画像の読込み

画像の読み込みには特別なソフトが必要になりますが、UNIXではほとんどのビューワでこれらの形式の画像が読み込めるのに対し、Windowsでは標準のビューワには対応していません。

Windows上でこれらの画像形式を表示するには Susie というソフトがお勧めです。

Susieはプラグインの追加により様々な画像形式にも対応するというソフトで、PPM/PGM/PBMの画像形式もプラグインの追加により表示が可能となります。

Susie HP

 C言語による画像の入出力例

C言語による画像書き出しの例を以下に示します。

ソースのダウンロード:

PGMファイル作成例[pnm_gray.c]出力画像(pnm_p5.pgm)
#include <stdio.h>
#include <math.h>
#include "pnm_lib.h"

//-----------------------------------------------------------------
void edit_image(PNMInfo pi,PIXEL* pdata);
//-----------------------------------------------------------------

#define IMG_SIZE (256*220)

int main()
{
    PNMInfo pi = {PNM_P5,256,220,255};
    PIXEL pdata[IMG_SIZE];
    // 画像部の編集
    edit_image(pi,pdata);
    // 画像の書き出し
    write_pnm("pnm_p5.pgm",pi,pdata);
    return 0;
}

//-----------------------------------------------------------------
// 画像部の編集
//-----------------------------------------------------------------
void edit_image(PNMInfo pi,PIXEL* pdata)
{
    int x,y;
    for(y=0;y<pi.ih;y++) for(x=0;x<pi.iw;x++){
        pdata[y*pi.iw + x] =
            (int)((double)x*((double)pi.imax/(double)pi.iw));
    }
}

PPMファイル作成例[pnm_color.c]出力画像(pnm_p6.ppm)
#include <stdio.h>
#include <math.h>
#include "pnm_lib.h"

//-----------------------------------------------------------------
void edit_image(PNMInfo pi,PIXEL* pdata);
//-----------------------------------------------------------------

#define IMG_SIZE (256*220)

int main()
{
    PNMInfo pi = {PNM_P6,256,220,255};
    PIXEL pdata[IMG_SIZE*3];
    // 画像部の編集
    edit_image(pi,pdata);
    // 画像の書き出し
    write_pnm("pnm_p6.ppm",pi,pdata);
    return 0;
}

//-----------------------------------------------------------------
// 画像部の編集
//-----------------------------------------------------------------
void edit_image(PNMInfo pi,PIXEL* pdata)
{
    int x,y;
    CPIXEL p;
    for(y=0;y<pi.ih;y++) for(x=0;x<pi.iw;x++){
        p.r = 0;
        p.g = (int)((double)x*((double)pi.imax/(double)pi.iw));
        p.b = (int)((double)x*((double)pi.imax/(double)pi.iw));
        pnmSetRGB(pi,pdata,x,y,p);
    }
}

PNM読取&画像反転の例[pnm_read.c]出力画像(pnm_rev.pnm)
#include <stdio.h>
#include <math.h>
#include "pnm_lib.h"

//-----------------------------------------------------------------
void edit_image(PNMInfo pi,PIXEL* pdata);
//-----------------------------------------------------------------

int main(int argc,char* argv[])
{
    char *ifile = NULL;
    PNMInfo pi;
    PIXEL* pdata;
    //--------------------------------------------------
    // ファイル名
    //--------------------------------------------------
    if(argc < 2) {
        fprintf(stderr,"USAGE: %s pnmfile\n",argv[0]);
        return 0;
    }
    ifile = argv[1];
    //--------------------------------------------------
    // PNM[PBM/PGM/PPM] 形式の読取
    //--------------------------------------------------
    if((pdata = read_pnm(ifile,&pi)) == NULL){
        fprintf(stderr,"pnm read error.\n");
        return 0;
    }
    // 画像部の編集: 画像値の反転
    edit_image(pi,pdata);
    // 画像の書き出し
    write_pnm("pnm_rev.pnm",pi,pdata);

    // 後片付け
    free(pdata);
    return 0;
}

//-----------------------------------------------------------------
// 画像部の編集: 画像値の反転
//-----------------------------------------------------------------
void edit_image(PNMInfo pi,PIXEL* pdata)
{
    int x,y;
    CPIXEL c; PIXEL p;
    for(y=0;y<pi.ih;y++) for(x=0;x<pi.iw;x++){
        if(pi.itype == PNM_P3 || pi.itype == PNM_P6){
            pnmGetRGB(pi,pdata,x,y,&c);
            c.r = pi.imax-c.r;
            c.g = pi.imax-c.g;
            c.b = pi.imax-c.b;
            pnmSetRGB(pi,pdata,x,y,c);
        } else {
            pnmGetPixel(pi,pdata,x,y,&p);
            p = pi.imax - p;
            pnmSetPixel(pi,pdata,x,y,p);
        }
    }
}
inserted by FC2 system