VC++6.0 用C语言怎么处理pgm图像

想飞的超人儿 2014-08-20 04:46:54
VC++6.0 用C语言输出一个像素为500*500的图像,灰度为个g(i,j)=100。
老师给了一个头文件如下:
mypgm.h
#define MAX_IMAGESIZE 1024
#define MAX_BRIGHTNESS 255
#define GRAYLEVEL 256 /* 灰度级 */
#define MAX_FILENAME 256 /* 最大文件名 */
#define MAX_BUFFERSIZE 256 /* 最大缓存 */
unsigned char image1[MAX_IMAGESIZE][MAX_IMAGESIZE],
image2[MAX_IMAGESIZE][MAX_IMAGESIZE];
int x_size1, y_size1,
x_size2, y_size2;
void load_image_data( );
void save_image_data( );
void load_image_data( )
{
char file_name[MAX_FILENAME];
char buffer[MAX_BUFFERSIZE];
FILE *fp;
int max_gray;
int x, y;
printf("-----------------------------------------------------\n");
printf(" 儌僲僋儘奒挷夋憸擖椡儖乕僠儞\n");
printf("-----------------------------------------------------\n");
printf("僼傽僀儖宍幃偼 pgm, 僶僀僫儕宍幃偲偟傑偡丏\n");
printf("擖椡僼傽僀儖柤 (*.pgm) : ");
scanf("%s",file_name);
fp = fopen( file_name, "rb" );/*读写打开一个二进制文件,只允许读写数据*/
if ( NULL == fp ){
printf("偦偺柤慜偺僼傽僀儖偼懚嵼偟傑偣傫丏\n");
exit(1);
/*exit()是用来正常结束进程的,exit(0)程序结束时返回0给系统,exit(1)程序结束时返回1给系统,
exit(n)程序结束时返回n给系统,这样系统就知道程序是怎么结束的~是出错结束的呢 还是正常结束的呢,一看返回值就知道了*/
}
/* fgets() 函数的功能是从fp所指文件中读入MAX_BUFFERSIZE-1个字符放入buffer为起始地址的空间内;
如果在未读满MAX_BUFFERSIZE-1个字符之时,已读到一个换行符或一个EOF(文件结束标志),
则结束本次读操作,读入的字符串中最后包含读到的换行符 */
fgets( buffer, MAX_BUFFERSIZE, fp );
if ( buffer[0] != 'P' || buffer[1] != '5' ){
printf("僼傽僀儖偺僼僅乕儅僢僩偑 P5 偲偼堎側傝傑偡丏\n");
exit(1);
}
x_size1 = 0;
y_size1 = 0;
while ( x_size1 == 0 || y_size1 == 0 ){
fgets( buffer, MAX_BUFFERSIZE, fp );
if ( buffer[0] != '#' ){
sscanf( buffer, "%d %d", &x_size1, &y_size1 );
}
}

max_gray = 0;
while ( max_gray == 0 ){
fgets( buffer, MAX_BUFFERSIZE, fp );
if ( buffer[0] != '#' ){
sscanf( buffer, "%d", &max_gray );
}
}

printf("墶偺夋慺悢 = %d, 廲偺夋慺悢 = %d\n", x_size1, y_size1 );
printf("嵟戝奒挷抣 = %d\n",max_gray);
if ( x_size1 > MAX_IMAGESIZE || y_size1 > MAX_IMAGESIZE ){
printf("憐掕抣 %d x %d 傪挻偊偰偄傑偡丏\n",
MAX_IMAGESIZE, MAX_IMAGESIZE);
printf("傕偆彮偟彫偝側夋憸傪巊偭偰壓偝偄丏\n");
exit(1);
}
if ( max_gray != MAX_BRIGHTNESS ){
printf("嵟戝奒挷抣偑晄揔愗偱偡丏\n");
exit(1);
}

for ( y = 0; y < y_size1; y ++ ){
for ( x = 0; x < x_size1; x ++ ){
image1[y][x] = (unsigned char)fgetc( fp );
}
}
printf("僨乕僞偼惓偟偔撉傒崬傑傟傑偟偨丏\n");
printf("-----------------------------------------------------\n");
fclose(fp);
}

void save_image_data()
{
char file_name[MAX_FILENAME];
FILE *fp;
int x, y;
printf("-----------------------------------------------------\n");
printf(" 儌僲僋儘奒挷夋憸乮pgm宍幃乯弌椡儖乕僠儞\n");
printf("-----------------------------------------------------\n");
printf("弌椡僼傽僀儖柤 (*.pgm) : ");
scanf("%s",file_name);
//以二进制写方式打开文件
fp = fopen(file_name, "wb");
//将一指定的字符串写入文件内
fputs( "P5\n", fp );
fputs( "# Created by Image Processing\n", fp );
fprintf( fp, "%d %d\n", x_size2, y_size2 );
fprintf( fp, "%d\n", MAX_BRIGHTNESS );
for ( y = 0; y < y_size2; y ++ ){
for ( x = 0; x < x_size2; x ++ ){
fputc( image2[y][x], fp );
}
}
printf("僨乕僞偼惓偟偔弌椡偝傟傑偟偨丏\n");
printf("-----------------------------------------------------\n");
fclose(fp);
}
我在源文件中是这样写的:
500.c
#include "stdio.h"
#include "mypgm.h"
void main()
{
int i,j,k,l;
x_size2=500;
y_size2=500;

for(i=0;i<x_size2;i++)
{
for(j=0;j<y_size2;j++)
{
image2[i][j]=100;
}
}
save_image_data();
//下面的部分不对
load_image_data();
for(k=0;k<x_size1;k++)
{
for(l=0;l<y_size1;l++)
{
printf(image1[k][l]);
}
}
}
在 load_image_data();函数之前,运行结果能够在输入的路径下(比如运行时输入C:\test.pgm)生成一个像素为500*500,灰度为100的.pgm格式的图片,老师要求将该图像在VC++6.0运行的窗口输出出来,我该怎么输出呢?上面500.c中load_image_data();下面的部分是不正确的,我以为load_image_data()是读取该图像,并把每一点的灰度值都存进了二位数组image1[x][y],可是怎么把图像数出来呢?求指导!
...全文
540 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
想飞的超人儿 2014-09-17
  • 打赏
  • 举报
回复
引用 8 楼 schlafenhamster 的回复:
创建 pgm 文件:创建的 pgm文件 可以 用 adcSee6.0 打开。 MakePgmFile() { if(m_pBits==0) // BYTE * m_pBits= (BYTE*) bm.bmBits; return; BYTE * pT=m_pBits; FILE *fp=fopen("Test.pgm", " wb"); fwrite("P5\n",1,3,fp); fwrite("#Test.pgm file\n",1,15,fp); char line[100]; sprintf(line,"%d %d\n",m_BmpWid,m_BmpHei);// m_BmpWid,m_BmpHei = bm.... fwrite(line,1,strlen(line),fp); fwrite("255\n", 1, 4,fp);// maxBrightness=255 // bits for(int h= m_BmpHei-1, h>=0;h--) { for(int w=0;w<m_BmpWid;w++) { BYTE gray=pT[m_BmpBPP /* =3 * / *h *m_BmpWid + m_bmBPP *w]; fwrite(&gray,1,1,fp); } } fclose(fp); } 手打 的 !
谢谢你帮我打了这么多!是我弄错了,老师只要求生成pgm图像,然后用看图软件打开就好了!嘿嘿。。。非常感谢。
schlafenhamster 2014-09-14
  • 打赏
  • 举报
回复
pipi20091001 2014-09-14
  • 打赏
  • 举报
回复
建议你研究一下“PGM”图像格式,看懂PGM是如何定义文件格式的,然后转换成位图也可以,或者说直接通过PGM按照文件格式输出
schlafenhamster 2014-09-02
  • 打赏
  • 举报
回复
调过的: void CPgmDlg::OnButton1() { // 创建 pgm 文件:创建的 pgm文件 可以 用 adcSee6.0 打开。 if(m_pBits==0) return; // BYTE *pTmp=(BYTE *)m_pBits; FILE *fp=fopen("Test.pgm", "wb"); fwrite("P5\n",1,3,fp); fwrite("#Test.pgm file\n",1,15,fp); char line[100]; sprintf(line,"%d %d\n",m_bmWid,m_bmHei); fwrite(line,1,strlen(line),fp); fwrite("255\n", 1, 4,fp);// maxBrightness=255 // bits for(int h= m_bmHei-1; h>=0;h--) { for(int w=0;w<m_bmWid;w++) { BYTE gray=pTmp[m_bmBPP * h * m_bmWid + m_bmBPP * w]; fwrite(&gray,1,1,fp); } } fclose(fp); } // gray void CPgmDlg::OnButton3() { // TODO: Add your control notification handler code here if(m_pBits==0) return; // BYTE *pTmp=(BYTE *)m_pBits; DWORD all=m_bmBPP*m_bmHei*m_bmWid; BYTE *pEnd=pTmp+all-m_bmBPP; while(pTmp<pEnd) { BYTE gray=(11*pTmp[0]+59*pTmp[1]+30*pTmp[2])/100; pTmp[0]=pTmp[1]=pTmp[2]=gray; pTmp += m_bmBPP; } Invalidate(); } // CPgmDlg::CPgmDlg(CWnd* pParent /*=NULL*/) : CDialog(CPgmDlg::IDD, pParent) { //{{AFX_DATA_INIT(CPgmDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // Load the background bitmap. HANDLE hBitmap = LoadImage (AfxGetInstanceHandle (), "头像.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); ASSERT (hBitmap != NULL); m_bitmap.Attach (hBitmap); // size BITMAP bm; m_bitmap.GetObject (sizeof (bm), &bm); m_bmWid = bm.bmWidth; m_bmHei = bm.bmHeight; m_bmBPP = bm.bmBitsPixel/8; // bits m_pBits = (BYTE*)bm.bmBits; // } void CPgmDlg::OnPaint() { CPaintDC dc(this); // device context for painting CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SelectObject(m_bitmap); dc.BitBlt(0,0,m_bmWid,m_bmHei,&memDC,0,0,SRCCOPY); // CDialog::OnPaint(); } // // Implementation protected: HICON m_hIcon; CBitmap m_bitmap; int m_bmWid; int m_bmHei; int m_bmBPP; const BYTE *m_pBits;
schlafenhamster 2014-09-02
  • 打赏
  • 举报
回复
创建 pgm 文件:创建的 pgm文件 可以 用 adcSee6.0 打开。 MakePgmFile() { if(m_pBits==0) // BYTE * m_pBits= (BYTE*) bm.bmBits; return; BYTE * pT=m_pBits; FILE *fp=fopen("Test.pgm", " wb"); fwrite("P5\n",1,3,fp); fwrite("#Test.pgm file\n",1,15,fp); char line[100]; sprintf(line,"%d %d\n",m_BmpWid,m_BmpHei);// m_BmpWid,m_BmpHei = bm.... fwrite(line,1,strlen(line),fp); fwrite("255\n", 1, 4,fp);// maxBrightness=255 // bits for(int h= m_BmpHei-1, h>=0;h--) { for(int w=0;w<m_BmpWid;w++) { BYTE gray=pT[m_BmpBPP /* =3 * / *h *m_BmpWid + m_bmBPP *w]; fwrite(&gray,1,1,fp); } } fclose(fp); } 手打 的 !
schlafenhamster 2014-09-02
  • 打赏
  • 举报
回复
思路: 1. 打开一个 24(32) 的 bmp 文件 2. 如果是 彩色的 就 gray 成 灰色。 3. 输出 到 pgm 文件 4. 关键是 要 得到 bits HBITMAP hbmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(), lpszresourcename,IMAGE_BITMAP,0,0, LR_LOADFROMFILE); //装入位图 //下面得到bmp的Bitmap结构。 GetObject(bmp, sizeof(bm), (LPSTR)&bm); bm里的 bits 就是 你要 用的 数据。 24 位时 是 每 3个· 字节 一个 像素。
想飞的超人儿 2014-09-02
  • 打赏
  • 举报
回复
引用 2 楼 schlafenhamster 的回复:
http://wenku.baidu.com/link?url=uLK5LW41UttTaxXKUcul4e1zyzofNue20GKKWgZZ8aL6NVR9wuU_dVoDS8gCek05iyuq-VYa3xfMKbNVlAKCOo5cXPpz34IiZQBik8TxCtq
你好,我想请你帮我看一下上面的程序,我已经知道通过 save_image_data() 在一个路径下(比如C:\)生成一个pgm图像,然后通过头文件里的load_image_data()在同一路径下读取出刚刚生成的pgm图像,并将每一点保存在二维数组image1[][]里。现在我想要用两个for循环把该图像在C语言窗口输出出来,应该怎么弄呢?帮我看看吧,网上都查不到,万分感谢啦!
schlafenhamster 2014-08-21
  • 打赏
  • 举报
回复
参考: “创建PBM单色位图文件”0分 http://download.csdn.net/detail/schlafenhamster/7428757 “这是创建和显示PBM P1 ascii 的vc程序 另外有个PPM的程序:"旋转PPM rar"”
schlafenhamster 2014-08-20
  • 打赏
  • 举报
回复
P2 ascii 格式 P5 binary 格式 你的 save_image_data() 格式不对!
赵4老师 2014-08-20
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
shiter 2014-08-20
  • 打赏
  • 举报
回复
老师要求将该图像在VC++6.0运行的窗口输出出来,我该怎么输出呢? 搞一个对话框,完后把这个图片转化成位图格式,完后输出来? 我猜测。。。

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧