全部博文(150)
分类:
2010-02-01 12:09:59
PGM文件格式 PGM----Portable Graymap Format. pgm格式是灰度文件格式的最低标准. PGM文件的格式定义如下: 一个PGM文件由一个或多个PGM图象组成. 在多副图象之间,之前或之后没有任何数据存在. 每一个PGM 图像由以下部分组成: - 一个"magic number",它是用来标定文件格式的. pgm的magic number是"P5". - 空白区域(空格,TAB,回车,换行) - 图象宽, 十进制ASCII码 - 空白区域 - 图象高, 十进制ASCII码 - 空白区域 - 最大灰度值(Maxval), 十进制ASCII码.必须小于65536 - 新一行或另一个空白区域符 - 空栅化的一副宽*高的灰度值图象. 每个灰度值取值是从0到Maxval, 0表示黑,而Maxval表示白.每个灰度值用1-2个字节表示.如果 Maxval小于256,那行就是一个字节,否则为两个字节.最大字节(most significant byte)开始 - 每个灰度值是表示当前象素值在CIE Rec.709伽马校正之后的密度值. - 一个很普遍的PGM格式替代格式就是线性灰度值(不经过伽马校正), pnmgamma以这样的一个pgm文件为输入,输出一个标准的pgm文件 - #符号之后的一行为注释行,会被省略. - 每个象素的光栅值表示为一个十进制ASCII码值. - 每个象素的光栅值前后各有一个空格. 这样两个象素之间将有大于等于1个空格. - 每行不超过70个字. PGM文件示例: P5 24 7 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0 0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0 0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0 0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0 0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
下面是一个读取PGM文件并存储为BMP文件的程序:
// PGM2BMP.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
using namespace std;
class CPGMFile
{
private:
string m_sFileName;
int m_nWidth,m_nHeight;
BYTE *m_bPData;
int m_nMaxValue;
public:
CPGMFile(const string &fileName):m_sFileName(fileName),m_nWidth(0),m_nHeight(0),m_bPData(0),m_nMaxValue(0)
{
}
~CPGMFile()
{
if(m_bPData != 0)
{
delete []m_bPData;
m_bPData = 0;
}
}
bool ReadImage()
{
FILE *fp = fopen(m_sFileName.c_str(),"r");
if(!fp)
{
cout<<"open file failed!\n";
return false;
}
const int bufferSize = 256;
char buffer[bufferSize];
fgets(buffer,bufferSize,fp);
if (buffer[0] != 'P' || buffer[1] != '5')//"P5"
{
cout<<"This is not a PGM file!\n";
return false;
}
fgets(buffer,bufferSize,fp);
sscanf(buffer, "%d %d",&m_nWidth,&m_nHeight); //width and height
fgets(buffer,bufferSize,fp);
sscanf(buffer, "%d",&m_nMaxValue); //max value (In general it is equal to 255)
m_bPData = new BYTE[m_nWidth*m_nHeight]; //allocate memory for image data
if(!m_bPData)
{
cout<<"allocate memory failed\n";
return false;
}
int count = fread(m_bPData,sizeof(BYTE),m_nWidth*m_nHeight,fp);
fclose(fp);
return true;
}
void SaveImage(const string &fileName)
{
FILE* fp=fopen(fileName.c_str(),"wb");
if(!fp)
{
cout<<"open file failed!\n";
return ;
}
int i,j,num;
int p = (m_nWidth*3)%4;
BYTE a0;
BYTE a1;
BYTE a2;
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER bmpInfoHeaderPtr ;
bitmapFileHeader.bfType = 0x4D42;
bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // 54
bitmapFileHeader.bfSize = m_nWidth * m_nHeight + bitmapFileHeader.bfOffBits;
bitmapFileHeader.bfReserved1 = 0;
bitmapFileHeader.bfReserved2 = 0;
bmpInfoHeaderPtr.biSize = 40;
bmpInfoHeaderPtr.biWidth = m_nWidth;
bmpInfoHeaderPtr.biHeight = m_nHeight;
bmpInfoHeaderPtr.biPlanes = 1;
bmpInfoHeaderPtr.biBitCount = 24;
bmpInfoHeaderPtr.biCompression = 0;
bmpInfoHeaderPtr.biSizeImage = 0;
bmpInfoHeaderPtr.biXPelsPerMeter = 512; //any digit maybe
bmpInfoHeaderPtr.biYPelsPerMeter = 512; //any digit maybe
bmpInfoHeaderPtr.biClrUsed = 0;
bmpInfoHeaderPtr.biClrImportant = 0;
fwrite((void*) &bitmapFileHeader, 1, sizeof(BITMAPFILEHEADER), fp);
fwrite((void*) &bmpInfoHeaderPtr, 1, sizeof(BITMAPINFOHEADER), fp);
for(j=m_nHeight-1;j>=0;j--)
{
for(i=0;i{
a0 = m_bPData[j*m_nWidth+i];
a1 = a0;
a2 = a0;
fwrite(&a0,1,1,fp);
fwrite(&a1,1,1,fp);
fwrite(&a2,1,1,fp);
}
if(p!=0)
{
for(num=0;num<4-p;num++)
{
a0=0;
fwrite(&a0,1,1,fp);
}
}
}
fclose(fp);
}
};
int main(int argc, char* argv[])
{
CPGMFile pgmFile("lena.pgm");
if(pgmFile.ReadImage())
{
pgmFile.SaveImage("grot.bmp");
}
return 0;
}