⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3.cpp

📁 从24位真彩色bmp图上读取迷宫数据,然后找出路径,再在图上标出路径
💻 CPP
字号:
// 1.cpp : Defines the entry point for the console application.
//

#include   "stdafx.h"
#include   "stdio.h"      
#include   "conio.h"   
#include   <malloc.h>
#define m 514 //程序只能读取24位真彩色bmp图像,且最大为512*384(大于此值内存分配有问题)
#define n 386 //m,n分别取为514,386是为了在矩阵中给哨兵留出位置

struct way//定义结构体栈来记录路径
{
	int x;//记录矩阵行坐标
	int y;//记录矩阵列坐标
	int t;//记录该坐标已搜索方向数
}w[m*n];

//用来从bmp图像中读取0,1矩阵,用矩阵A记录,filename是bmp文件名
//*pLength,*pWidth带回图像长度,高度(单位:像素)
void ReadBmp(int A[][m],char *filename,int *pLength,int *pWidth)
{
    char   buffer [(m-2)*3];//24位bmp图一个像素占3位,buffer用来读取一行像素
    int i,j,k;
	FILE   *fpbmp,*fptxt;

    printf("请输入bmp文件名:");  //输入要读取的BMP文件名      
	scanf("%s",filename);   
     
	if((fpbmp=fopen(filename,"rb"))==NULL)        
	{            
		printf("Can't   open   file:   %s",buffer);           
		return;         
	}   
    
    fseek(fpbmp,18,SEEK_SET); //为了读取图像的宽度和高度  
    fread(pWidth,4,1,fpbmp);  //图象的宽度和高度都是一个32位整数 
    fread(pLength,4,1,fpbmp);   
    k=(*pWidth%4)?(4-*pWidth%4):0; //宽度修正值 
    fseek(fpbmp,54,SEEK_SET);//24位bmp没有颜色表,54位以后就是图像数据
    for(i=*pLength;i>=1;i--)//图像数据是倒序存放,故先读入的是最后一行
    {   
        fread(buffer,*pWidth,3,fpbmp);//读取一行像素,存放在buffer中  
        for(j=0;j<*pWidth;j++)   
        {   //当RGB分量都是0时,为黑色
			if( buffer[3*j]==0 && buffer[3*j+1]==0 && buffer[3*j+2]==0)
                   A[i][j+1]=1;   
			else   A[i][j+1]=0;  
         }   
        fseek(fpbmp,k,SEEK_CUR);  //每行读取完后修正宽度/   
     }   
     fclose(fpbmp);  

	 for(i=0,j=0;j<=*pWidth+1;j++)//设置哨兵
	     A[i][j]=1;
     for(i=*pLength+1,j=0;j<=*pWidth+1;j++)
	     A[i][j]=1;
     for(i=0,j=0;i<=*pLength+1;i++)
	     A[i][j]=1;
     for(i=0,j=*pWidth+1;i<=*pLength;i++)
	     A[i][j]=1;


	  fptxt=fopen("1.txt","w");//输出矩阵到2.txt中
      for(i=0;i<=*pLength+1;i++)   
      {
		  for(j=0;j<=*pWidth+1;j++)   
		  {   
              fprintf(fptxt,"%d",A[i][j]);   
		  }   
		  fprintf(fptxt,"%s","\n");
	  }
    fclose(fptxt);    
}

//用来在迷宫矩阵A中寻找出路,用*ptop带回栈的长度。
//矩阵实际大小为(length+2)*(width+2)
void FineWay(int *ptop,int A[n][m],int width,int length)
{
	int i,j;
    int dy[]={1,1,0,-1,-1,-1,0,1};//方向数组
	int dx[]={0,1,1,1,0,-1,-1,-1}; 
	FILE *fptxt;
    
	*ptop = 0;
	w[*ptop].x = 1;//起始点坐标
	w[*ptop].y = 1;

    while(i!=length || j!=width)
    {
	   w[*ptop].t=0;
	   while (w[*ptop].t<8)
	   {
		   i=w[*ptop].x+dx[w[*ptop].t];//搜索方向的下一点坐标
		   j=w[*ptop].y+dy[w[*ptop].t];          
		   if(A[i][j]==1)//走不通则换下一个方向
		       w[*ptop].t++;
		   else break;//某方向能走通则跳出
	   }

	   if(w[*ptop].t==8)//8个方向都走不通 
	       *ptop--;//去掉栈顶元素,退回上一点
	   else//*ptop].t!=8表明有一个方向可以走通
	   {
			A[i][j] =1;	//走过坐标变1,不允许再次回到这一点		
			(*ptop)++;//栈的长度加一
            w[*ptop].x = i;//入栈,记录新位置坐标
			w[*ptop].y = j;			   
		}

		if(*ptop==-1)
		{
			printf("迷宫没有出路");
		    break;
		}	 
	}
 
    fptxt=fopen("2.txt","w");//将出路路径输出到2.txt
    for(i=0;i<=*ptop;i++)
	    fprintf(fptxt,"%d,%d\n",w[i].x,w[i].y);  
	fclose(fptxt);    
}

//用来在图像中用红色画出出路
void ReportBmp(struct way w[],int top,char *filename,int width,int length)
{
	FILE *fpbmp;
	int i,k;
	long a=0x00FB0000;//RGB为该值时,像素为红色

    if((fpbmp=fopen(filename,"rb+"))==NULL)   
    {   
         printf("Can't   open   file:   %s",filename);   
         return;   
    }  

	k=(width%4)?(4-width%4):0;////宽度修正值 
	
	for(i=0;i<=top;i++)//fseek定位到图像第w[top].x行,第w[top].y个象素
	{   //因数据倒序存放,在w[i]点之前存放有length-w[i].x行像素数据
	    fseek(fpbmp,54+(length-w[i].x)*(width*3+k)+(w[i].y-1)*3,SEEK_SET);
	    fwrite(&a,3,1,fpbmp);
	}
	fclose(fpbmp);
}

void   main()   
{   
     
	 char filename[20];//用来读取图像名
     int  k,top,length,width;       
     int  A[n][m]; 
 
     ReadBmp(A,filename,&length,&width);//读取矩阵,带回图像长度和宽度
	   
	 FineWay(&top,A,width,length);//寻找出路
    	  
	 ReportBmp(w,top,filename,width,length);//在图像上画出出路 
}   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -