关闭

【数字图像处理一】BMP图像的读取

标签: 数字图像处理显示BMP图像VC
1059人阅读 评论(0) 收藏 举报
分类:

使用工具:VC6.0

实践具体操作:请参考《用MFC读取BMP图像》:http://blog.csdn.net/u013580497/article/details/44619869

该博文内容:如何编写读取和显示BMP图像的函数。

① 函数参数:

BOOL ReadImage(LPSTR ImageFileName, char *oImage) 
{	
}
调用方式:

ReadImage(ImgDlgFileName, OrgImage);
参数:

char ImgDlgFileName[]={"D:\\test.bmp"};//图像路径,注意必须是24位bmp图像,其它格式可以用画图另存为转成bmp。
char OrgImage[1024*1024];		//图像数据,获取RGB等信息
注意如果图片读取出来全是黑色的话,需要把1024*1024改大点,例如2048*2048。

② 建立变量

BOOL ReadImage(LPSTR ImageFileName, char *oImage) 
{	
	int r, g, b,j;
	OFSTRUCT of;
	HFILE Image_fp;//头文件
	BITMAPFILEHEADER BMFH;//文件头
	BITMAPINFOHEADER BMIH;//信息头
	Image_fp = OpenFile(ImageFileName, &of, OF_READ);//读取指定路径下的文件
	if (Image_fp == HFILE_ERROR)//判断读取图像的时候是否出错。 
	{	MessageBox(NULL, ImageFileName, "打开文件出错信息", MB_OK);
		return FALSE;
	}
}

OFSTRUCT of;负责从路径中读取出 HFILE Image_fp。

HFILE Image_fp 从BITMAP(BMP)图像中读取出 BITMAPFILEHEADER 和 BITMAPINFOHEADER。

BITMAPFILEHEADER 和 BITMAPINFOHEADER这两个类用于读取出24位BMP图像的信息。

BOOL ReadImage(LPSTR ImageFileName, char *oImage) 
{	
	///////////////////////   1.  建立变量   /////////////////////////////    
        int r, g, b,j;
	OFSTRUCT of;
	HFILE Image_fp;//头文件
	BITMAPFILEHEADER BMFH;//文件头
	BITMAPINFOHEADER BMIH;//信息头
	Image_fp = OpenFile(ImageFileName, &of, OF_READ);//读取指定路径下的文件
	if (Image_fp == HFILE_ERROR) 
	{	MessageBox(NULL, ImageFileName, "打开文件出错信息", MB_OK);
		return FALSE;
	}
        ///////////////////////// 2.  变量初始化  ///////////////////////////
      _lread(Image_fp, &BMFH,sizeof(BITMAPFILEHEADER));//初始化BITMAP FILE HEADER变量
      _lread(Image_fp,&BMIH,sizeof(BITMAPINFOHEADER));//初始化BITMAOP INFO HEADER变量}


③ 接下来可以用BITMAPFILEHEADER和BITMAPINFOHEADER读取出图像信息

BOOL ReadImage(LPSTR ImageFileName, char *oImage) 
{	
	///////////////////////   1.  建立变量   /////////////////////////////
        int r, g, b,j;
	OFSTRUCT of;
	HFILE Image_fp;//头文件
	BITMAPFILEHEADER BMFH;//文件头
	BITMAPINFOHEADER BMIH;//信息头
	Image_fp = OpenFile(ImageFileName, &of, OF_READ);//读取指定路径下的文件
	if (Image_fp == HFILE_ERROR) 
	{	MessageBox(NULL, ImageFileName, "打开文件出错信息", MB_OK);
		return FALSE;
	}
        ///////////////////////// 2.  变量初始化  ///////////////////////////
        _lread(Image_fp, &BMFH,sizeof(BITMAPFILEHEADER));//初始化BITMAP FILE HEADER变量
	_lread(Image_fp,&BMIH,sizeof(BITMAPINFOHEADER));//初始化BITMAOP INFO HEADER变量
        ////////////////////////  3.  读取图像的相关信息   //////////////////
        wImage=BMIH.biWidth;//指定图像的宽度,单位是像素
        hImage=BMIH.biHeight;//指定图像的高度,单位是像素
        biSizeImage=BMIH.biSizeImage;//图像的字节数
}

④ 读取BMP图像的全部RGB信息

首先要说明一点,BMP图像的内容并不全是图像内容,前面还有一点别的信息,例如宽度高度什么的,所以在读取BMP图像的时候要跳过这些信息。

例如用数组表示的话:


所以我们要使用:

_llseek(Image_fp,BMFH.bfOffBits,FILE_BEGIN);

来跳过开头信息。

BOOL ReadImage(LPSTR ImageFileName, char *oImage) 
{	
	///////////////////////   1.  建立变量   /////////////////////////////
        int r, g, b,j;
	OFSTRUCT of;
	HFILE Image_fp;//头文件
	BITMAPFILEHEADER BMFH;//文件头
	BITMAPINFOHEADER BMIH;//信息头
	Image_fp = OpenFile(ImageFileName, &of, OF_READ);//读取指定路径下的文件
	if (Image_fp == HFILE_ERROR) 
	{	MessageBox(NULL, ImageFileName, "打开文件出错信息", MB_OK);
		return FALSE;
	}
        ///////////////////////// 2.  变量初始化  ///////////////////////////
        _lread(Image_fp, &BMFH,sizeof(BITMAPFILEHEADER));//初始化BITMAP FILE HEADER变量
	_lread(Image_fp,&BMIH,sizeof(BITMAPINFOHEADER));//初始化BITMAOP INFO HEADER变量
        ////////////////////////  3.  读取图像的相关信息   //////////////////
       	wImage=BMIH.biWidth;//指定图像的宽度,单位是像素
	hImage=BMIH.biHeight;//指定图像的高度,单位是像素
        biSizeImage=BMIH.biSizeImage;//图像的字节数
        ////////////////////////  4.  读取BMP的RGB信息   ////////////////////
        _llseek(Image_fp,BMFH.bfOffBits,FILE_BEGIN);//BfOffBits  位图数据距文件头的偏移量
        _lread(Image_fp,oImage,biSizeImage);//往oImage写入RBG信息。
        _lclose(Image_fp);//关闭头文件
}
这样oImage数组就获得了图像的RGB信息。


⑤ 现在可以用oImage数组来输出图像了,不过为了方便编程我们可以编一个struct。

struct RGB{
	BYTE R;
	BYTE G;
	BYTE B;
};
这样就可以建一个RGB二维数组来,存储图像中每一块的RGB信息,然后知道图像的宽和高,就可以用循环来显示图像。

⑥ 把oImage转化成RGB[][]

    要注意的是:

我们通过 biSizeImage=BMIH.biSizeImage;获取了总字节数。

那么每一行的字节数就是BitRow=biSizeImage/hImage,其中hImage表示图像的高。

而部分图像中数组oImage中wImage*3 ≠ BitRow(wImage表示图像的高,*3表示RGB有三个),会造成图像倾斜。


所以每行都需要从BitRow * i 开始读取,i 表示当前行数。

<span style="font-size:14px;">BOOL ReadImage(LPSTR ImageFileName, char *oImage) 
{	
	///////////////////////   1.  建立变量   /////////////////////////////
	int r, g, b;
	OFSTRUCT of;
	HFILE Image_fp;//头文件
	BITMAPFILEHEADER BMFH;//文件头
	BITMAPINFOHEADER BMIH;//信息头
	Image_fp = OpenFile(ImageFileName, &of, OF_READ);//读取指定路径下的文件
	if (Image_fp == HFILE_ERROR) 
	{	MessageBox(NULL, ImageFileName, "打开文件出错信息", MB_OK);
		return FALSE;
	}
	///////////////////////// 2.  变量初始化  ///////////////////////////
	_lread(Image_fp, &BMFH,sizeof(BITMAPFILEHEADER));//初始化BITMAP FILE HEADER变量
	_lread(Image_fp,&BMIH,sizeof(BITMAPINFOHEADER));//初始化BITMAOP INFO HEADER变量
	////////////////////////  3.  读取图像的相关信息   //////////////////
	wImage=BMIH.biWidth;//指定图像的宽度,单位是像素
	hImage=BMIH.biHeight;//指定图像的高度,单位是像素
	biSizeImage=BMIH.biSizeImage;//图像的字节数
	////////////////////////  4.  读取BMP的RGB信息   /////////////////////
	_llseek(Image_fp,BMFH.bfOffBits,FILE_BEGIN);//BfOffBits  位图数据距文件头的偏移量
	_lread(Image_fp,oImage,biSizeImage);//往oImage写入RBG信息。
	_lclose(Image_fp);//关闭头文件
	////////////////////////  5.  将oImage转成RGB[][]  ///////////////////
	Imagebyte=new RGB*[hImage];//建立动态数组
	BitRow=biSizeImage/hImage;//  每一行的位图数据占用的字节数
	for(unsigned long i=0;i<hImage;i++){
		Imagebyte[i]=new RGB[wImage];//建立动态数组
		BitTheRow=i*BitRow;
		for (unsigned long j=0; j<wImage; j++) {
			r= (BYTE)(oImage[BitTheRow+j*3+2]);
			g= (BYTE)(oImage[BitTheRow+j*3+1]);
			b= (BYTE)(oImage[BitTheRow+j*3]);
			Imagebyte[i][j].R=r;
			Imagebyte[i][j].G=g;
			Imagebyte[i][j].B=b;
		}
	}
	return true;
}</span>

至此ReadImage的函数已经读取完毕。


接下来就是编写ShowImage的函数。

void ShowImage(int xPos,int yPos)
{	
	unsigned long i,j;
    for(i=0;i<hImage;i++){
		for(j=0;j<wImage;j++){
				//当hImage为整数的时候,Bmp图像是倒过来的,所以输出的时候要从最下面开始输出,方法是hImage-i。
			SetPixel(hWinDC,j+xPos,hImage-i+yPos,RGB(Imagebyte[i][j].R,Imagebyte[i][j].G,Imagebyte[i][j].B));
		}
	}
}
主要就是遍历一个hImage * wImage的二维数组。

根据RGB三基色绘制一个图块的函数:

SetPixel(当前窗口,X坐标,Y坐标,RGB(R值,G值,B值));
调用ShowImage函数后图像显示如下:



全局变量有:

HDC  hWinDC;//图像显示区域
unsigned long wImage=0,hImage=0;
int BitTheRow=0;
int BitRow=0;
int biSizeImage=0;
RGB **Imagebyte;
char ImgDlgFileName[]={"D:\\tree1.bmp"};
char OrgImage[1024*1024];		//图像数据

本案例下载地址:http://download.csdn.net/detail/u013580497/8876395

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:62443次
    • 积分:1413
    • 等级:
    • 排名:千里之外
    • 原创:80篇
    • 转载:6篇
    • 译文:1篇
    • 评论:15条
    最新评论