📄 3.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 + -