|
//---------------------------------------------------------------------------
#include<stdio.h>
//---------------------------------------------------------------------------
#define SkipWhiteSpacesM(fp)\
if(fp)\
{\
char ch;\
do\
{ \
ch = getc(fp);\
if(!(ch==' ' || ch=='\t' || ch=='\r' || ch=='\n'))\
{\
ungetc(ch,fp);\
break;\
}\
}while(ch!=EOF);\
}
//---------------------------------------------------------------------------
#define SkipCommentM(fp)\
if(fp)\
{\
char buff[128];\
buff[0] = getc(fp);\
if(buff[0]=='#')\
{\
fgets(buff,128,fp);\
while(strlen(buff)==127) fgets(buff,128,fp);\
}\
else\
{\
ungetc(buff[0],fp);\
}\
}
//---------------------------------------------------------------------------
#define SkipWhiteSpaces SkipWhiteSpacesM
#define SkipComment SkipCommentM
//---------------------------------------------------------------------------
enum PGMFormat{pgmf1Byte=1,pgmf2Byte};
class TPGM
{
private:
char Type[3];
int Width,Height,MaxVal,ImageByteSize;
PGMFormat Format;
BYTE *ImageBuffer;
void CreateImageBuffer(int w,int h,int bpp)
{
delete ImageBuffer;
ImageBuffer = new BYTE[w*h*(int)bpp];
}
public:
TPGM():Width(0),Height(0),MaxVal(0),ImageBuffer(NULL)
{
}
~TPGM()
{
delete ImageBuffer;
}
bool LoadFromFile(const char* filePath)
{
bool ret=false;
FILE *fp;
try{
if(NULL==(fp=fopen(filePath,"rb"))) return false;
ZeroMemory(Type,sizeof(Type));
fscanf(fp,"%2s",Type);
if((Type[0]!='P' && Type[0]!='p') || Type[1]!='5') return false;
SkipWhiteSpaces(fp);
SkipComment(fp);
fscanf(fp,"%i%i%i",&Width,&Height,&MaxVal);
if(MaxVal<256) Format=pgmf1Byte;
else Format=pgmf2Byte;
ImageByteSize = Width*Height*(int)Format;
CreateImageBuffer(Width,Height,(int)Format);
fread(ImageBuffer,ImageByteSize,1,fp);
ret=true;
}__finally{
fclose(fp);
}
return ret;
}
const char* GetType(void) const
{
return Type;
}
int GetWidth(void) const
{
return Width;
}
int GetHeight(void) const
{
return Height;
}
int GetMaxVal(void) const
{
return MaxVal;
}
PGMFormat GetFormat(void) const
{
return Format;
}
int GetImageByteSize(void) const
{
return ImageByteSize;
}
const BYTE* GetImageBuffer(void) const
{
return ImageBuffer;
}
};
TPGM g_pgm;
//---------------------------------------------------------------------------
void __fastcall TForm1::btnOpenClick(TObject *Sender)
{
if(!OpenDialog1->Execute()) return;
g_pgm.LoadFromFile((OpenDialog1->FileName+"").c_str());
lblType->Caption = g_pgm.GetType();
lblWidth->Caption = g_pgm.GetWidth();
lblHeight->Caption = g_pgm.GetHeight();
lblMaxVal->Caption = g_pgm.GetMaxVal();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
if(g_pgm.GetWidth()==0) return;
LPBITMAPINFO bmpi=(LPBITMAPINFO)new BYTE[sizeof(BITMAPINFO)+256*sizeof(RGBQUAD)];
ZeroMemory(bmpi, sizeof(BITMAPINFO));
bmpi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpi->bmiHeader.biPlanes=1;
bmpi->bmiHeader.biWidth=g_pgm.GetWidth();
bmpi->bmiHeader.biHeight=g_pgm.GetHeight();
bmpi->bmiHeader.biBitCount=(int)g_pgm.GetFormat()*8;
bmpi->bmiHeader.biCompression = BI_RGB;
bmpi->bmiHeader.biSizeImage=g_pgm.GetImageByteSize();
if(g_pgm.GetFormat()==pgmf1Byte)
{
bmpi->bmiHeader.biClrUsed=256;
bmpi->bmiHeader.biClrImportant=256;
for(int i=0;i<256;i++)
{
bmpi->bmiColors[i].rgbRed = i;
bmpi->bmiColors[i].rgbBlue = i;
bmpi->bmiColors[i].rgbGreen = i;
bmpi->bmiColors[i].rgbReserved = NULL;
}
}
SetDIBitsToDevice(PaintBox1->Canvas->Handle,
0,0
,bmpi->bmiHeader.biWidth,bmpi->bmiHeader.biHeight
,0,0
,0,bmpi->bmiHeader.biHeight
,g_pgm.GetImageBuffer(),bmpi,DIB_RGB_COLORS);
delete bmpi;
}
좀해보자 님이 쓰신 글 :
: PGM 파일은 비트맵이랑 다른게 없다고 생각되는데요
: 헤더파일에 대한 정보만 조금씩 다르고 (예를 들면 비트맵 헤더에 'B','M' 이라는 정보가 있듯이 PGM에는 'p','5' 정보가 있구요 이미 제가 올린파일을 살펴보면 헤더정보를 읽는 부분이 있습니다.
: 그리구 나머지 이미지 데이터에 대한것은 _ppA가 전부 갖고 있구요
: 선배의 조언으로는 픽셀당 수식을 사용한 변환과정은 필요 없다고 하는군요
: 그냥 단순히 _ppA의 첫번째 주소만 scanline[0]에 넘겨주면 된다고 합니다.
: 실제로 _ppA데이터를 읽어보면 가로세로 크리와 사이즈, 데이터가 들어있더군요.
: 주소값만 잘 넘겨주라는데 이게 힘드네요 ^^;
:
: 메일주소라도 알려주시면 이미지는 보내드리겠습니다.
:
: 님이 쓰신 글 :
: : bool KPGM::Load(char* szFile) 메서드 내의 아래 코드를 보니 1 픽셀 당 1 바이트이군요.
: : //read data
: : for(int i=0; i<nRow; i++)
: : fread(_ppA[i],1,nCol,fp);
: : 그렇다면,
: : void __fastcall TForm1::SpeedButton1Click(TObject *Sender) 내의 gbitmap의 PixelFormat를 pf8bit로 명시적으로 지정해주셔야 합니다.
: :
: : 제가 PGM, PPM 확장자를 가진 이미지 파일에 대해 아는 바가 없어서 더이상 말씀드릴 수가 없군요.
: : 혹 해당 파일형식에 대한 명세를 가지고 계시면 이미지 파일과 함께 여기에 올려보세요.
: : 제가 한 번 살펴보겠습니다.
|