BMP图像的读写8位和24位要点.docx

上传人:b****3 文档编号:10465312 上传时间:2023-05-26 格式:DOCX 页数:19 大小:212.02KB
下载 相关 举报
BMP图像的读写8位和24位要点.docx_第1页
第1页 / 共19页
BMP图像的读写8位和24位要点.docx_第2页
第2页 / 共19页
BMP图像的读写8位和24位要点.docx_第3页
第3页 / 共19页
BMP图像的读写8位和24位要点.docx_第4页
第4页 / 共19页
BMP图像的读写8位和24位要点.docx_第5页
第5页 / 共19页
BMP图像的读写8位和24位要点.docx_第6页
第6页 / 共19页
BMP图像的读写8位和24位要点.docx_第7页
第7页 / 共19页
BMP图像的读写8位和24位要点.docx_第8页
第8页 / 共19页
BMP图像的读写8位和24位要点.docx_第9页
第9页 / 共19页
BMP图像的读写8位和24位要点.docx_第10页
第10页 / 共19页
BMP图像的读写8位和24位要点.docx_第11页
第11页 / 共19页
BMP图像的读写8位和24位要点.docx_第12页
第12页 / 共19页
BMP图像的读写8位和24位要点.docx_第13页
第13页 / 共19页
BMP图像的读写8位和24位要点.docx_第14页
第14页 / 共19页
BMP图像的读写8位和24位要点.docx_第15页
第15页 / 共19页
BMP图像的读写8位和24位要点.docx_第16页
第16页 / 共19页
BMP图像的读写8位和24位要点.docx_第17页
第17页 / 共19页
BMP图像的读写8位和24位要点.docx_第18页
第18页 / 共19页
BMP图像的读写8位和24位要点.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

BMP图像的读写8位和24位要点.docx

《BMP图像的读写8位和24位要点.docx》由会员分享,可在线阅读,更多相关《BMP图像的读写8位和24位要点.docx(19页珍藏版)》请在冰点文库上搜索。

BMP图像的读写8位和24位要点.docx

BMP图像的读写8位和24位要点

南通大学计算机科学与技术学院

《数字图像处理》课程实验

报告书

 

实验名BMP文件的读写(8位和24位)

班级计121

姓名张进

学号1213022016

 

2014年6月16日

1、实验内容

1、了解BMP文件的结构

2、8位位图和24位位图的读取

2、BMP图形文件简介

BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。

Windows系统内部各图像绘制操作都是以BMP为基础的。

Windows3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependentbitmap)文件格式。

Windows3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independentbitmap)格式(注:

Windows3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。

BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。

位图文件可看成由4个部分组成:

位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列,它具有如下所示的形式。

 

位图文件的组成 

结构名称 

符号 

位图文件头(bitmap-file header)

BITMAPFILEHEADER

bmfh

位图信息头(bitmap-information header)

BITMAPINFOHEADER

bmih

彩色表(color table)

RGBQUAD

aColors[]

图象数据阵列字节

BYTE

aBitmapBits[]

位图文件结构内容摘要

 

偏移量 

域的名称 

大小 

内容 

  

  

  

图象文件 

0000h

文件标识

2 bytes

两字节的内容用来识别位图的类型:

 

‘BM’ :

 Windows 3.1x, 95, NT, … 

‘BA’ :

OS/2 Bitmap Array 

‘CI’ :

OS/2 Color Icon 

‘CP’ :

OS/2 Color Pointer 

‘IC’ :

 OS/2 Icon 

‘PT’ :

OS/2 Pointer

注:

因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。

 

0002h

File Size

1 dword

用字节表示的整个文件的大小

 

0006h

Reserved

1 dword

保留,必须设置为0

 

000Ah

Bitmap Data Offset

1 dword

从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量

 

000Eh

Bitmap Header Size

1 dword

位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。

下面的长度表示:

 

28h - Windows 3.1x, 95, NT, … 

0Ch - OS/2 1.x 

F0h - OS/2 2.x

注:

在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。

所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。

这样才能确保程序的兼容性。

 

0012h

Width

1 dword

位图的宽度,以象素为单位

 

0016h

Height

1 dword

位图的高度,以象素为单位

 

001Ah

Planes

1 word

位图的位面数(注:

该值将总是1)

图象 

信息 

头 

  

 

001Ch

Bits Per Pixel

1 word

每个象素的位数 

1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。

你可以自己定义这两种颜色) 

4 - 16 色位图 

8 - 256 色位图 

16 - 16bit 高彩色位图 

24 - 24bit 真彩色位图 

32 - 32bit 增强型真彩色位图

 

001Eh

Compression

1 dword

压缩说明:

 

0 - 不压缩 (使用BI_RGB表示) 

1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示) 

2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示) 

3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)

 

0022h

Bitmap Data Size

1 dword

用字节数表示的位图数据的大小。

该数必须是4的倍数

 

0026h

HResolution

1 dword

用象素/米表示的水平分辨率

 

002Ah

VResolution

1 dword

用象素/米表示的垂直分辨率

 

002Eh

Colors

1 dword

位图使用的颜色数。

如8-比特/象素表示为100h或者 256.

 

0032h

Important Colors

1 dword

指定重要的颜色数。

当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要

调色板数据

根据BMP版本的不同而不同

Palette

N * 4 byte

调色板规范。

对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:

 

1字节用于蓝色分量

1字节用于绿色分量

1字节用于红色分量

1字节用于填充符(设置为0)

图象数据

根据BMP版本及调色板尺寸的不同而不同

Bitmap Data

xxx bytes

该域的大小取决于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。

3、读写涉及的原理

1、图像的二值化的基本原理

图像的二值化处理就是讲图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。

即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。

在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。

为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。

所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。

如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。

如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。

动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。

2、图像的反色原理

对于彩色图像的R、G、B各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。

如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理

四、读写转换代码

#include

#include

#include

#include

#include

#include

#include

#include

//---------------------------------------------------------------------------------------

//以下该模块是完成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)

return0;

//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0

intcolorTablesize=0;

if(biBitCount==8)

colorTablesize=1024;

//待存储图像数据每行字节数为4的倍数

intlineByte=(width*biBitCount/8+3)/4*4;

//以二进制写的方式打开文件

FILE*fp=fopen(bmpName,"wb");

if(fp==0)

return0;

//申请位图文件头结构变量,填写文件头信息

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);

//申请位图信息头结构变量,填写信息头信息

BITMAPINFOHEADERhead;

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;

//写位图信息头进内存

fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);

//如果灰度图像,有颜色表,写入文件

if(biBitCount==8)

fwrite(pColorTable,sizeof(RGBQUAD),256,fp);

//写位图数据进文件

fwrite(imgBuf,height*lineByte,1,fp);

//关闭文件

fclose(fp);

return1;

}

//----------------------------------------------------------------------------------------

//以下为像素的读取函数

voiddoIt()

{

//读入指定BMP文件进内存

charreadPath[]="D:

\\pic\\24dog.BMP";

readBmp(readPath);

//输出图像的信息

cout<<"width="<

//循环变量,图像的坐标

//每行字节数

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<8;fen_ge_lie++)//64*64列矩阵循环

{

//--------------------------------------------

for(L1=hang;L1>hang-8;L1--)//8*8矩阵行

{

for(intL2=lie;L2

{

m=*(pBmpBuf+L1*lineByte+L2);

outfile<

count_xiang_su++;

if(count_xiang_su%8==0)//每8*8矩阵读入文本文件

{

outfile<

}

}

}

//---------------------------------------------

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",ios:

:

in|ios:

:

trunc);

if(!

outfile)

{

cout<<"openerror!

"<

exit

(1);

}

elseif(biBitCount==24)

{//彩色图像

for(inti=0;i

{

for(intj=0;j

{

for(intk=0;k<3;k++)//每像素RGB三个分量分别置0才变成黑色

{

//*(pBmpBuf+i*lineByte+j*3+k)-=40;

m=*(pBmpBuf+i*lineByte+j*3+k);

outfile<

count_xiang_su++;

if(count_xiang_su%8==0)

{

outfile<

}

//n++;

}

n++;

}

}

cout<<"总的像素个素为:

"<

cout<<"----------------------------------------------------"<

}

//将图像数据存盘

charwritePath[]="D:

\\pic\\24newdog.BMP";//图片处理后再存储

saveBmp(writePath,pBmpBuf,bmpWidth,bmpHeight,biBitCount,pColorTable);

//清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间

delete[]pBmpBuf;

if(biBitCount==8)

delete[]pColorTable;

}

voidmain()

{

doIt();

}

五、运行结果

24位位图24dog.bmp如下:

原图像的属性:

读取结果:

生成的新图片:

8位位图读取8dog.bmp如下

图片属性:

读取的结果:

生成的新图片:

6、心得体会

大一学的c++,现在却发现忘得差不多了,在程序实现上遇到了困难。

但是本次实验确实又再一次的让我接触了c语言。

这次实验掌握了BMP文件的读取,第一次对图像有这么深的认识了解。

对图像的组成不再是以前那种错误的认识,有收获。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2