PNM画像からBMP画像への変換

PNM画像フォーマット(白黒/濃淡/カラー)からをBMP画像への変換例です。

ビットマップの表示では、1ライン当たりのデータ数が4Byte(long)に限られているため、ビットマップファイルからのデータの読取後の表示には注意が必要です。1ラインが4で割り切れない場合は足りないバイト数を加えて計算する必要があります。また、画像の表示する方向が異なるため、画像方向を変換する必要があります。

 ダウンロード

PNM画像からBMP画像への変換(pnm2bmp.c)
//-----------------------------------------------------------------
// pnm2bmp.c:
//     PNM(白黒/濃淡/カラー)画像からビットマップへの変換
//            Last Update: <2004/12/05 10:08:24 A.Murakami>
//-----------------------------------------------------------------
#include <stdio.h>
#include <math.h>
#include "bmp.h"
#include "pnm_lib.h"

// パス名の分割
void split_path(char* fpath,char* dir,char* file,char* ext);

int main(int argc,char* argv[])
{
    char *ifile,ofile[MAX_PATH];
    BMPInfo bi; PNMInfo pi;
    PIXEL *pdata,*bdata;
    char dir[MAX_PATH],file[MAX_PATH],ext[10];
    //--------------------------------------------------
    // ファイル名
    //--------------------------------------------------
    if(argc<2) {
        fprintf(stderr,"USAGE: %s pnmfile\n",argv[0]);
        return 0;
    }
    ifile = argv[1];
    split_path(ifile,dir,file,ext);
    sprintf(ofile,"%s.bmp",file);
    //--------------------------------------------------
    // PPM形式の読取
    //--------------------------------------------------
    pdata = read_pnm(ifile,&pi);
    if(pdata == NULL){
        fprintf(stderr,"pnm read error.\n");
        return 0;
    }
    //--------------------------------------------------
    // BMP形式へのデータ変換
    //--------------------------------------------------
    if(pi.itype==PNM_P3 || pi.itype==PNM_P6){
        bdata = ppm2bmp(pi,pdata);
    } else {
        bdata = pgm2bmp(pi,pdata);
    }
    //--------------------------------------------------
    // ビットマップ出力
    //--------------------------------------------------
    fprintf(stderr,"**output to %s\n",ofile);
    init_bmp(&bi,pi.itype,pi.iw,pi.ih);
    // 出力
    output_bmp(ofile,bi,bdata);
    fprintf(stderr,"done.\n",ofile);
    // 後片付け
    free(pdata); free(bdata);
    return 0;
}

//-----------------------------------------------------------------
// パス名の分割
//-----------------------------------------------------------------
void split_path(char* fpath,char* dir,char* file,char* ext)
{
    int i,len=strlen(fpath);
    // file and ext
    for(i=len-1;i>=0;i--)
        if(fpath[i]=='.') break;
    strncpy(ext,fpath+i,len-i);
    strncpy(file,fpath,i);
    ext[len-i] = '\0'; file[i] = '\0';
    // dir
    len = i;
    for(i=len-1;i>=0;i--)
        if(file[i]=='/') break;
    i++;
    strncpy(dir,file,i);
    strncpy(file,file+i,len-i);
    dir[i] = '\0'; file[len-i] = '\0';
}
inserted by FC2 system