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

原创 2015年07月07日 10:05:45

使用工具: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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

【数字图像处理】一.MFC详解显示BMP格式图片

本文主要是讲述《数字图像处理》系列栏目中的文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的《数字图像处理》课程和以前的项目叙述讲解.从四个方面进行叙述:BMP图...

【无浪】用MFC读取BMP图像

MFC读取数字图像....

C语言 BMP图片处理

http://feng88724.iteye.com/blog/316651   首页 资讯   精华   论坛   问答   博客   专栏   群组 ...

关于bmp save图象颠倒解决方法

(thinkvd开发日志)在开发swf to video,保存bmp图时,刚好图象上下颠倒, 以前用了一个简单算法把图象数据倒过来,在网上查了一下,据说有一个标志位,反复看了BITMAPFILEHEA...
  • notton
  • notton
  • 2011-04-22 10:43
  • 1622

【数字图像处理】<纯C++>读取、裁剪、缩放、旋转和存储8位bmp灰度图像

C++实现以下功能:1、实现对硬盘中的8位BMP图像的读取和存储;2、实现对指定矩形框区域图像的剪切;3、实现对任意形状图像的任意比例缩放;4、实现对任意形状图像的任意角度选装。 程序编辑环境:在vi...

【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现

通过我这些天用C++读写bmp图像的经历,摸索再摸索,终于对bmp文件的结构、操作有了一定的了解,下面就大概介绍bmp图片纯C++的读取、旋转和保存的实现过程。 要用C++读取bmp图片文件,首...

【数字图像处理】bmp文件详细分析

最近在做数字图像处理的助教,每一次都有一个实验,这里我想把每一次实验的内容写出来给自己做一个备注,以后查阅起来也比较方便,相关内容都是从网上查阅,然后自己进行整理和分析的。 第一个作业:BMP文件转...

数字图像处理--BMP文件的读入和保存

BMP文件是Windows系统标准图像文件格式,是一种将内存中的图像数据不经过压缩直接按位存盘的文件格式,所以被称为位图(bitmap),文件扩展名为BMP. BMP文件被分为以下四个部分:位图文件头...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)