从文件对话框中读取一幅bmp图片,并解析图片信息(eg:获取分辨率)

void CCameraTest2View::OnOpen() 
{
// TODO: Add your control notification handler code here
//
读文件获取图片
//
CFileDialog dlg(TRUE, "*.bmp", NULL, NULL, "位图文件 (*.bmp)|*.bmp|所有文件 (*.*)|*.*||", NULL);
CString strImageName;
if(IDOK == dlg.DoModal())
{
strImageName = dlg.GetFileName();
Invalidate(); // 不能去掉,否则图片显示不正常 
}
long t1 = GetTickCount();

// 读取BMP文件


CFile ImageFile(strImageName, CFile::modeRead); // 以只读的方式,创建文件对象
long ImageLength = ImageFile.GetLength(); // 获取文件字节个数

BYTE  *pImage1; 
pImage1 = new BYTE[ImageLength];  // 定义一个字节数组,用来保存bmp图片数据

ImageFile.Read(pImage1,ImageLength); // 读取图像,把数据保存在pImage1这个堆内存中
Decore(pImage1); // 调用这个函数,把图片进行解析   执行完这个函数之后,图像指针指向了真正的位图数据,可以对像素进行操作了

 //获取图片的宽度和高度信息, tagIMAGEHEADER IMAGEHEADER;这句话在其他地方定义了~~

int width = IMAGEHEADER.biWidth;
int heigth = IMAGEHEADER.biHeight;
width = (width+3)/4*4;  // 这个语句的作用是把图片高度都变成4的倍数,方便后期进行处理

int offbit = IMAGEHEADER.bfOffBits;

}


其中,Decore函数的定义如下:

bool CCameraTest2View::Decore(BYTE* pimageno)
{
pImageData = pimageno;   // pImageData 是在View头文件中定义的,也是一个字节数组(或者是一个对堆内存的指针),以后对图片文件操作,就是对这个指针进行操作

IMAGEHEADER.bfType = *(WORD *)(pImageData);pImageData+=2;
IMAGEHEADER.bfSize = *(DWORD *)(pImageData);pImageData+=4;
IMAGEHEADER.bfReserved1 = *(WORD *)(pImageData);pImageData+=2;
IMAGEHEADER.bfReserved2 = *(WORD *)(pImageData);pImageData+=2;
IMAGEHEADER.bfOffBits = *(DWORD *)(pImageData);pImageData+=4;

IMAGEHEADER.biSize = *(DWORD *)(pImageData);pImageData+=4;
IMAGEHEADER.biWidth = *(long *)(pImageData);pImageData+=4;
IMAGEHEADER.biHeight = *(long *)(pImageData);pImageData+=4;
IMAGEHEADER.biPlanes = *(WORD *)(pImageData);pImageData+=2;
IMAGEHEADER.biBitCount = *(WORD *)(pImageData);pImageData+=2;
IMAGEHEADER.biCompression = *(DWORD *)(pImageData);pImageData+=4;
IMAGEHEADER.biSizeImage = *(DWORD *)(pImageData);pImageData+=4;
IMAGEHEADER.biXPelsPerMeter = *(long *)(pImageData);pImageData+=4;
IMAGEHEADER.biYPelsPerMeter = *(long *)(pImageData);pImageData+=4;
IMAGEHEADER.biClrUsed = *(DWORD *)(pImageData);pImageData+=4;
IMAGEHEADER.biClrImportant = *(DWORD *)(pImageData);pImageData+=4;
pImageData +=sizeof(RGBQUAD)*256; // 这个是调色板信息占用的字节,执行完这句话之后,图像指针就调出了位图文件图、位图信息头、调色板等,进入到了真正的位图数据

return 1;
}



tagIMAGEHEADER IMAGEHEADER;// 这句话是在View头文件中定义的,tagIMAGEHEADER是我们自己写的一个结构体,它封装了MFC库函数中自带的位图文件头、位图信息头两个结构体,变成了一个结构体,方便调用,如下:


struct tagIMAGEHEADER
{
// 位图文件头
WORD bfType;// 文件类型,如果是BMP格式的图像,则是0x4D42,也就是字符BM
DWORD bfSize;// 文件大小,单位是字节
WORD bfReserved1;// 保留,必须设置为0
WORD bfReserved2;// 保留,必须设置为0
DWORD bfOffBits;// 从文件头开始到实际的图像数据之间的字节的偏移量

// 位图信息头
DWORD biSize;// BITMAPINFOHEADER结构的字节数
long biWidth;// 图像宽度,单位为像素
long biHeight;// 图像高度,单位为像素
WORD biPlanes;// 位面数,总是设置为1
WORD biBitCount;// 比特数/象素,其值为1、4、8、16、24或32 
DWORD biCompression;// 图象数据压缩的类型
DWORD biSizeImage;// 图像的大小,单位是字节 biSizeImage = biWidth * biHeight * biBitCount / 8!!!!!
long biXPelsPerMeter;// 水平分辨率,用象素/米表示 
long biYPelsPerMeter;// 说明垂直分辨率,用象素/米表示 
DWORD biClrUsed;// 位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项) 
DWORD biClrImportant;// 对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
};

你可能感兴趣的:(图像处理方面(基于C++))