您的位置:首页 > 其它

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

2015-07-07 10:05 896 查看
使用工具:VC6.0

实践具体操作:请参考《用MFC读取BMP图像》:/article/10930874.html

该博文内容:如何编写读取和显示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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: