BMP图像的读写8位和24位汇总Word文档下载推荐.docx
- 文档编号:812011
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:19
- 大小:212.02KB
BMP图像的读写8位和24位汇总Word文档下载推荐.docx
《BMP图像的读写8位和24位汇总Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《BMP图像的读写8位和24位汇总Word文档下载推荐.docx(19页珍藏版)》请在冰点文库上搜索。
位图文件结构内容摘要
偏移量
域的名称
大小
内容
图象文件
头
0000h
文件标识
2
bytes
两字节的内容用来识别位图的类型:
‘BM’
:
Windows
3.1x,
95,
NT,
…
‘BA’
OS/2
Bitmap
Array
‘CI’
Color
Icon
‘CP’
Pointer
‘IC’
‘PT’
Pointer
注:
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。
0002h
File
Size
1
dword
用字节表示的整个文件的大小
0006h
Reserved
保留,必须设置为0
000Ah
Data
Offset
从文件开始到位图数据开始之间的数据(bitmap
data)之间的偏移量
000Eh
Header
位图信息头(Bitmap
Info
Header)的长度,用来描述位图的颜色、压缩方法等。
下面的长度表示:
28h
-
0Ch
1.x
F0h
2.x
在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。
所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。
这样才能确保程序的兼容性。
0012h
Width
位图的宽度,以象素为单位
0016h
Height
位图的高度,以象素为单位
001Ah
Planes
word
位图的位面数(注:
该值将总是1)
图象
信息
头
001Ch
Bits
Per
Pixel
每个象素的位数
单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。
你可以自己定义这两种颜色)
4
16
色位图
8
256
16bit
高彩色位图
24
24bit
真彩色位图
32
32bit
增强型真彩色位图
001Eh
Compression
压缩说明:
0
不压缩
(使用BI_RGB表示)
RLE
8-使用8位RLE压缩方式(用BI_RLE8表示)
4-使用4位RLE压缩方式(用BI_RLE4表示)
3
Bitfields-位域存放方式(用BI_BITFIELDS表示)
0022h
用字节数表示的位图数据的大小。
该数必须是4的倍数
0026h
HResolution
用象素/米表示的水平分辨率
002Ah
VResolution
用象素/米表示的垂直分辨率
002Eh
Colors
位图使用的颜色数。
如8-比特/象素表示为100h或者
256.
0032h
Important
指定重要的颜色数。
当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
调色板数据
根据BMP版本的不同而不同
Palette
N
*
byte
调色板规范。
对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:
1字节用于蓝色分量
1字节用于绿色分量
1字节用于红色分量
1字节用于填充符(设置为0)
图象数据
根据BMP版本及调色板尺寸的不同而不同
Data
xxx
该域的大小取决于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。
3、读写涉及的原理
1、图像的二值化的基本原理
图像的二值化处理就是讲图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。
即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。
为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。
所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。
如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。
如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。
动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。
2、图像的反色原理
对于彩色图像的R、G、B各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。
如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理
四、读写转换代码
#include<
math.h>
#include<
iomanip.h>
stdlib.h>
windows.h>
stdio.h>
iostream.h>
fstream.h>
//---------------------------------------------------------------------------------------
//以下该模块是完成BMP图像(彩色图像是24bitRGB各8bit)的像素获取,并存在文件名为xiang_su_zhi.txt中
unsignedchar*pBmpBuf;
//读入图像数据的指针
intbmpWidth;
//图像的宽
intbmpHeight;
//图像的高
RGBQUAD*pColorTable;
//颜色表指针
intbiBitCount;
//图像类型,每像素位数
//-------------------------------------------------------------------------------------------
//读图像的位图数据、宽、高、颜色表及每像素位数等数据进内存,存放在相应的全局变量中
boolreadBmp(char*bmpName)
{
FILE*fp=fopen(bmpName,"
rb"
);
//二进制读方式打开指定的图像文件
if(fp==0)
return0;
//跳过位图文件头结构BITMAPFILEHEADER
fseek(fp,sizeof(BITMAPFILEHEADER),0);
//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
BITMAPINFOHEADERhead;
fread(&
head,sizeof(BITMAPINFOHEADER),1,fp);
//获取图像宽、高、每像素所占位数等信息
bmpWidth=head.biWidth;
bmpHeight=head.biHeight;
biBitCount=head.biBitCount;
//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
intlineByte=(bmpWidth*biBitCount/8+3)/4*4;
//灰度图像有颜色表,且颜色表表项为256
if(biBitCount==8)
{
//申请颜色表所需要的空间,读颜色表进内存
pColorTable=newRGBQUAD[256];
fread(pColorTable,sizeof(RGBQUAD),256,fp);
}
//申请位图数据所需要的空间,读位图数据进内存
pBmpBuf=newunsignedchar[lineByte*bmpHeight];
fread(pBmpBuf,1,lineByte*bmpHeight,fp);
fclose(fp);
//关闭文件
return1;
//读取文件成功
}
//-----------------------------------------------------------------------------------------
//给定一个图像位图数据、宽、高、颜色表指针及每像素所占的位数等信息,将其写到指定文件中
boolsaveBmp(char*bmpName,unsignedchar*imgBuf,intwidth,intheight,intbiBitCount,RGBQUAD*pColorTable)
//如果位图数据指针为0,则没有数据传入,函数返回
if(!
imgBuf)
//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0
intcolorTablesize=0;
colorTablesize=1024;
//待存储图像数据每行字节数为4的倍数
intlineByte=(width*biBitCount/8+3)/4*4;
//以二进制写的方式打开文件
wb"
//申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADERfileHead;
fileHead.bfType=0x4D42;
//bmp类型
//bfSize是图像文件4个组成部分之和
fileHead.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize+lineByte*height;
fileHead.bfReserved1=0;
fileHead.bfReserved2=0;
//bfOffBits是图像文件前3个部分所需空间之和
fileHead.bfOffBits=54+colorTablesize;
//写文件头进文件
fwrite(&
fileHead,sizeof(BITMAPFILEHEADER),1,fp);
//申请位图信息头结构变量,填写信息头信息
head.biBitCount=biBitCount;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=height;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=lineByte*height;
head.biWidth=width;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//写位图信息头进内存
head,sizeof(BITMAPINFOHEADER),1,fp);
//如果灰度图像,有颜色表,写入文件
fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
//写位图数据进文件
fwrite(imgBuf,height*lineByte,1,fp);
//关闭文件
//----------------------------------------------------------------------------------------
//以下为像素的读取函数
voiddoIt()
//读入指定BMP文件进内存
charreadPath[]="
D:
\\pic\\24dog.BMP"
;
readBmp(readPath);
//输出图像的信息
cout<
<
"
width="
bmpWidth<
height="
bmpHeight<
biBitCount="
biBitCount<
endl;
//循环变量,图像的坐标
//每行字节数
intlineByte=(bmpWidth*biBitCount/8+3)/4*4;
//循环变量,针对彩色图像,遍历每像素的三个分量
intm=0,n=0,count_xiang_su=0;
//将图像左下角1/4部分置成黑色
ofstreamoutfile("
图像像素.txt"
ios:
:
in|ios:
trunc);
if(biBitCount==8)//对于灰度图像
{
//------------------------------------------------------------------------------------
//以下完成图像的分割成8*8小单元,并把像素值存储到指定文本中。
由于BMP图像的像素数据是从
//左下角:
由左往右,由上往下逐行扫描的
intL1=0;
inthang=63;
intlie=0;
//intL2=0;
//intfen_ge=8;
for(intfen_ge_hang=0;
fen_ge_hang<
8;
fen_ge_hang++)//64*64矩阵行循环
for(intfen_ge_lie=0;
fen_ge_lie<
fen_ge_lie++)//64*64列矩阵循环
//--------------------------------------------
for(L1=hang;
L1>
hang-8;
L1--)//8*8矩阵行
for(intL2=lie;
L2<
lie+8;
L2++)//8*8矩阵列
m=*(pBmpBuf+L1*lineByte+L2);
outfile<
m<
"
count_xiang_su++;
if(count_xiang_su%8==0)//每8*8矩阵读入文本文件
//---------------------------------------------
hang=63-fen_ge_hang*8;
//64*64矩阵行变换
lie+=8;
//64*64矩阵列变换
//该一行(64)由8个8*8矩阵的行组成
hang-=8;
//64*64矩阵的列变换
lie=0;
//64*64juzhen
//doublexiang_su[2048];
//ofstreamoutfile("
xiang_su_zhi.txt"
outfile)
openerror!
exit
(1);
elseif(biBitCount==24)
{//彩色图像
for(inti=0;
i<
bmpHeight;
i++)
for(intj=0;
j<
bmpWidth;
j++)
for(intk=0;
k<
3;
k++)//每像素RGB三个分量分别置0才变成黑色
//*(pBmpBuf+i*lineByte+j*3+k)-=40;
m=*(pBmpBuf+i*lineByte+j*3+k);
if(count_xiang_su%8==0)
//n++;
n++;
总的像素个素为:
n<
----------------------------------------------------"
//将图像数据存盘
charwritePath[]="
\\pic\\24newdog.BMP"
//图片处理后再存储
saveBmp(writePath,pBmpBuf,bmpWidth,bmpHeight,biBitCount,pColorTable);
//清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
delete[]pBmpBuf;
delete[]pColorTable;
voidmain()
doIt();
五、运行结果
24位位图24dog.bmp如下:
原图像的属性:
读取结果:
生成的新图片:
8位位图读取8dog.bmp如下
图片属性:
读取的结果:
6、心得体会
大一学的c++,现在却发现忘得差不多了,在程序实现上遇到了困难。
但是本次实验确实又再一次的让我接触了c语言。
这次实验掌握了BMP文件的读取,第一次对图像有这么深的认识了解。
对图像的组成不再是以前那种错误的认识,有收获。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- BMP 图像 读写 24 汇总