//VC++6.0调试通过。但是由于本人最近较忙,所以只做了处理24位位图和32位位图的功能,1、4、8、16位位图从原理上来说是一样的,不过情况稍微复杂一点。你自己解决吧。
//注意,运行时必须要在控制台(cmd窗口)运行,如果直接在编译器那里编译时,是看不到希望的结果的。有问题的话这两天可以百度找我,再过几天就回家了,得明年才回来。
#include<windows.h>
#include<iostream>
#include<fstream>
#include <iomanip>
using namespace std;
/*
位图文件分四个部分:
1.文件头
2.文件信息头
3.调色板
4.实际位图数据
//位图文件文件头,2*3+4*2=14字节
typedef struct tagBITMAPFILEHEADER
{
WORD bfType;//文件类型,必须为0x424D,由于WORD类型存放数据是先低字节、再高字节,所以实际上在判断时要用0x4d42(见代码,或者可直接用10进制的数19778),即"BM",'B'=0x42,'M'='0x4d'
DWORD bfSize;//文件大小
WORD bfReserved1;//保留字,必须设置为0,可不考虑,下同
WORD bfReserved2;
DWORD bfOffBits;//文件头到实际位图数据的偏移字节数,即前三部分长度之和
}BITMAPFILEHEADER;
//文件信息头,2*2+4*9=40字节
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;//此结构长度,为40
LONG biWidth;//图像宽度,单位为像素
LONG biHeight;//图像高度,单位为像素
WORD biPlanes;//必须为1
WORD biBitCount;//颜色位数,常用有:1(黑白2色图)、4(16色图)、8(256色图)、24(真彩色图)。新bmp格式还支持32位(增强型真彩色图)
DWORD biCompression;//指定位图是否压缩,有效值:BI_RGB、BI_RLE8、BI_RLE4、BI_BITFIELDS,均为Windows定义好的常量
DWORD biSizeImage;//实际位图数据占用的字节数
LONG biXPelsPerMeter;//目标设备水平分辨率,单位:像素/米
LONG biYPelsPerMeter;//目标设备垂直分辨率,单位:像素/米
DWORD biClrUsed;//图像实际用的到颜色数,如果为0,则实际用到的颜色数为:2的biBitCount次方
DWORD biClrImportant;//重要的颜色数,为0时表示所有颜色都重要
}BITMAPINFOHEADER;
//位图调色板(真彩色不需要),是一个数组,共biClrUsed个元素,若该值为0,则共有2的biBitCount次方个元素。每个元素是一个颜色表结构:
//颜色表结构
typedef struct tagRGBQUAD
{
BYTE rgbBlue; //蓝色分量
BYTE rgbGreen; //绿色分量
BYTE rgbRed; //红色分量
BYTE rgbReserved;//保留值
}RGBQUAD;
*/
class CBmp
{
public:
//读图像文件信息
bool ReadInfo(char FilePath[]);
//写图像灰度信息到文本文件
bool WriteToTxt(char FilePath[]);
CBmp();
virtual ~CBmp();
private:
BITMAPFILEHEADER m_sBMFH; //位图文件头
BITMAPINFOHEADER m_sBMIH; //位图信息头
RGBQUAD * m_pPalette; //调色板
BYTE * m_pBData; //位图数据
};
CBmp::CBmp()
{
m_pPalette = NULL;
m_pBData = NULL;
}
CBmp::~CBmp()
{
if(m_pPalette!=NULL)
{
delete [] m_pPalette;
m_pPalette = NULL;
}
if(m_pBData!=NULL)
{
delete [] m_pBData;
m_pBData = NULL;
}
}
//读图像文件
bool CBmp::ReadInfo(char FilePath[])
{
int nSize; //用来记录调色板的大小
ifstream fin;
fin.open(FilePath,ios::binary);
if(!fin)
{
cerr<<"Open file error!"<<endl;
return false;
}
//读取文件头
fin.read((char *)(&m_sBMFH),sizeof(BITMAPFILEHEADER));
// 判断是否BMP格式
if(m_sBMFH.bfType!=0x4d42)
{
cout<<"该文件不是BMP格式的文件!"<<endl;
return false;
}
//读取文件信息头
fin.read((char *)(&m_sBMIH),sizeof(BITMAPINFOHEADER));
//计算调色板的大小
nSize = m_sBMFH.bfOffBits - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER);
if(nSize!=0)
{
//读取调色板
m_pPalette = new RGBQUAD [nSize/4];
fin.read((char *)(m_pPalette),nSize);
}
//读取图像数据
m_pBData = new BYTE [m_sBMIH.biSizeImage];
fin.read((char *)(m_pBData),m_sBMIH.biSizeImage);
return true;
}
//写图像灰度信息到文本文件
bool CBmp::WriteToTxt(char FilePath[])
{
// 选用的灰度转换公式不同,所得的结果基本上是一致的,但是会稍有差别。
// Gray = (R*38 + G*75 + B*15) >> 7; //高精度转灰度公式
// Gray = R*0.299 + G*0.587 + B*0.114 //使用浮点计算,速度较慢
int k = 0,i,j;
int r,g,b;
int Gray;
BYTE *pt;
ofstream fout;
int t=0;
j = strlen(FilePath);
char *TxtFilePath = new char [j+1]; //记录灰度值的文本文件路径
TxtFilePath[j-3] = 't';
TxtFilePath[j-2] = 'x';
TxtFilePath[j-1] = 't';
TxtFilePath[j] = '\0';
for(i=j-4;i>=0;i--)
TxtFilePath[i] = FilePath[i] ;
switch(m_sBMIH.biBitCount)
{
case 1: //1、4、8位的位图有调色板,要先读取调色板,根据索引找到真实的图像RGB值,再转换。
cout<<"黑白2色(1位)位图的处理暂未实现!"<<endl;
break;
case 4:
cout<<"16色(4位)位图的处理暂未实现!"<<endl;
break;
case 8:
cout<<"256色(8位)位图的处理暂未实现"<<endl;
break;
case 16: //16位位图无调色板,一般为前5位记录R值,中6位记录G值,后5位记录B值
cout<<"16位位图的处理暂未实现"<<endl;
break;
case 24:
if(m_sBMIH.biWidth*3%4!=0)t=4-m_sBMIH.biWidth*3%4; //位图数据要求每行字节数必须是4的倍数,不足补齐t
fout.open(TxtFilePath,ios::out);
for(i=m_sBMIH.biHeight-1;i>=0;i--)
{
fout<<"第"<<m_sBMIH.biHeight-i<<"行:\n";
for(j=0;j<m_sBMIH.biWidth;j++)
{
pt = m_pBData+i*(m_sBMIH.biWidth*3+t)+3*j ;
r = (int)(*pt);
g = (int)(*(pt+1));
b = (int)(*(pt+2));
// Gray = (r*0.299+g*0.587+b*0.114);
Gray = (r*38 + g*75 + b*15) >> 7;
fout<<setiosflags(ios::left)<<setw(4)<<Gray;
}
fout<<endl;
}
fout.close();
break;
case 32:
//每行字节数必是4的倍数,所以不用补齐
fout.open(TxtFilePath,ios::out);
for(i=m_sBMIH.biHeight-1;i>=0;i--)
{
fout<<"第"<<m_sBMIH.biHeight-i<<"行\n";
for(j=0;j<m_sBMIH.biWidth;j++)
{
pt = m_pBData+i*(m_sBMIH.biWidth*4+t)+4*j ;
r = (int)(*pt);
g = (int)(*(pt+1));
b = (int)(*(pt+2));
// Gray = (r*0.299+g*0.587+b*0.114);
Gray = (r*38 + g*75 + b*15) >> 7;
fout<<setiosflags(ios::left)<<setw(4)<<Gray;
}
fout<<endl;
}
fout.close();
break;
default:
return false;
}
cout<<"灰度值记录在文件"<<TxtFilePath<<"中"<<endl;
delete [] TxtFilePath;
return true;
}
int main(int argc,char *argv[])
{
if(argc !=2 )
{
cout<<"输入参数错误,正确形式:\nyourprogram filePath"<<endl;
return 0;
}
CBmp Bitmap;
if( Bitmap.ReadInfo(argv[1]) )
Bitmap.WriteToTxt(argv[1]);
else
{
cout<<"读取文件出错"<<endl;
return 0;
}
return 1;
}
没有合适的资源?快使用搜索试试~ 我知道了~
vc++图像灰度值分析
共18个文件
idb:2个
pdb:2个
exe:2个
需积分: 50 29 下载量 166 浏览量
2012-04-09
18:06:03
上传
评论
收藏 3.65MB RAR 举报
温馨提示
vc++图像灰度值分析 打印成txt文档,分析图像灰度值。。用于图像分割前,分析
资源推荐
资源详情
资源评论
收起资源包目录
sy1.rar (18个子文件)
sy1
Release
vc60.idb 49KB
sy1.obj 95KB
sy1.exe 180KB
sy1.pch 5.2MB
sy1.dsw 512B
sy1.dsp 3KB
sy1.ncb 41KB
sy1.opt 48KB
sy1.bmp 1.57MB
Debug
vc60.pdb 140KB
sy1.pdb 1.09MB
vc60.idb 185KB
sy1.obj 296KB
sy1.ilk 799KB
sy1.exe 552KB
sy1.pch 5.2MB
sy1.cpp 6KB
sy1.plg 1KB
共 18 条
- 1
资源评论
软件老王
- 粉丝: 1w+
- 资源: 67
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功