Huffman编码及解码Word格式.docx
- 文档编号:19795524
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:20
- 大小:20.13KB
Huffman编码及解码Word格式.docx
《Huffman编码及解码Word格式.docx》由会员分享,可在线阅读,更多相关《Huffman编码及解码Word格式.docx(20页珍藏版)》请在冰豆网上搜索。
,node[i].color,node[i].lson,node[i].rson);
//二进制读方式打开指定的图像文件
.bhd"
FILE*fp=fopen(NameStr,"
rb"
if(fp==0){
//跳过位图文件头结构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,InfLen/8,fp);
//关闭文件
fclose(fp);
return1;
}
voidHuffmanDecode()
//获取编码信息
inti,j,tmp;
InfLen/8;
i++)
{
j=i*8+7;
tmp=*(pBmpBuf+i);
while(tmp>
0)
ImgInf[j]=tmp%2;
tmp/=2;
j--;
/*for(i=0;
InfLen;
%d"
ImgInf[i]);
*/
//解码
intp=NodeStart;
//遍历指针位置
j=0;
i=0;
do
if(node[p].color>
=0)
*(pBmpBuf+j)=node[p].color;
%d"
*(pBmpBuf+j));
j++;
p=NodeStart;
if(ImgInf[i]==1)
p=node[p].lson;
elseif(ImgInf[i]==0)
p=node[p].rson;
i++;
}while(i<
=InfLen);
\nj:
%d\n"
j);
/*********************
Huffman编码
//Huffman编码初始化
voidHuffmanCodeInit()
inti;
256;
i++)//灰度值记录清零
Num[i]=0;
//初始化哈夫曼树
600;
node[i].color=-1;
node[i].lson=node[i].rson=-1;
node[i].num=-1;
node[i].mark=0;
NodeNum=0;
//深搜遍历Huffman树获取编码值
charCodeTmp[300];
voiddfs(intpos,intlen)
//遍历左儿子
if(node[pos].lson!
=-1)
CodeTmp[len]='
1'
;
dfs(node[pos].lson,len+1);
else
if(node[pos].color!
CodeLen[node[pos].color]=len;
\0'
strcpy(CodeStr[node[pos].color],CodeTmp);
//遍历右儿子
0'
dfs(node[pos].rson,len+1);
else{
//寻找值最小的节点
intMinNode()
inti,j=-1;
if(!
node[i].mark)
if(j==-1||node[i].num<
node[j].num)
j=i;
if(j!
NodeStart=j;
node[j].mark=1;
returnj;
//编码主函数
voidHuffmanCode()
inti,j,k,a,b;
256;
{//创建初始节点
Feq[i]=(float)Num[i]/(float)(bmpHeight*bmpWidth);
//计算灰度值频率
if(Num[i]>
node[NodeNum].color=i;
node[NodeNum].num=Num[i];
node[NodeNum].lson=node[NodeNum].rson=-1;
//叶子节点无左右儿子
NodeNum++;
while
(1)
{//找到两个值最小的节点,合并成为新的节点
a=MinNode();
if(a==-1)
break;
b=MinNode();
if(b==-1)
//构建新节点
node[NodeNum].color=-1;
node[NodeNum].num=node[a].num+node[b].num;
node[NodeNum].lson=a;
node[NodeNum].rson=b;
//node[a].mark=node[b].mark=1;
//根据建好的Huffman树编码(深搜实现)
dfs(NodeStart,0);
//屏幕输出编码
intsum=0;
Huffman编码信息如下:
sum+=CodeLen[i]*Num[i];
灰度值:
%3d频率:
%f码长:
%2d编码:
%s\n"
i,Feq[i],CodeLen[i],CodeStr[i]);
//printf("
原始总码长:
%d\n"
bmpWidth*bmpHeight*8);
Huffman编码总码长:
sum);
压缩比:
%.3f:
1\n"
(float)(bmpWidth*bmpHeight*8)/(float)sum);
//记录图像信息
InfLen=0;
bmpHeight;
for(j=0;
j<
bmpWidth;
j++)
lpBuf=(unsignedchar*)pBmpBuf+lineByte*i+j;
for(k=0;
k<
CodeLen[*(lpBuf)];
k++)
ImgInf[InfLen++]=(int)(CodeStr[*(lpBuf)][k]-'
//再编码数据
)
*(pBmpBuf+j)=Change2to10(i);
i+=8;
/******************************
主函数
******************************/
intmain(intargc,char**argv)
intord;
//命令
charc;
clock_tstart,finish;
inttotal_time;
//CStringstr;
本程序提供以下功能\n\n\t1.256色灰度BMP图像Huffman编码\n\t2.Huffman编码BMP文件解码\n\t3.退出\n\n请选择需要执行的命令:
"
scanf("
%d%c"
ord,&
c);
if(ord==1)
\n---256色灰度BMP图像Huffman编码---\n"
\n请输入要编码图像名称:
%s"
str);
//读入指定BMP文件进内存
charreadPath[100];
strcpy(readPath,str);
strcat(readPath,"
.bmp"
if(readBmp(readPath))
//输出图像的信息
\n图像信息:
\nwidth=%d,height=%d,biBitCount=%d\n"
bmpWidth,bmpHeight,biBitCount);
if(biBitCount==8)
//编码初始化
HuffmanCodeInit();
//计算每个灰度值出现的次数
Num[*(lpBuf)]+=1;
//调用编码
start=clock();
HuffmanCode();
finish=clock();
total_time=(finish-start);
识别一张耗时:
%d毫秒"
total_time);
//将图像数据存盘
charwritePath[100];
//保存编码后的bmp
strcpy(writePath,str);
strcat(writePath,"
_Huffman.bhd"
saveBmp(writePath,pBmpBuf,bmpWidth,bmpHeight,biBitCount,pColorTable);
//保存Huffman编码信息和编码树
_Huffman.bpt"
saveInfo(writePath,lineByte);
\n编码完成!
编码信息保存在%s_Huffman文件中\n\n"
本程序只支持256色BMP编码!
//清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
delete[]pBmpBuf;
delete[]pColorTable;
\n-----------------------------------------------\n\n\n"
elseif(ord==2)
\n---Huffman编码BMP文件解码---\n"
\n请输入要解码文件名称:
//编码解码初始化
if(readHuffman(str))
{//读取文件
HuffmanDecode();
//Huffman解码
//保存解码后的bmp
_Decode.bmp"
InfLen=bmpWidth*bmpHeight*8;
system(writePath);
\n解码完成!
保存为%s_Decode.bmp\n\n"
elseif(ord==3)
/*ANSICrequiresmaintoreturnint.*/
编码:
#include<
stdlib.h>
stdio.h>
string.h>
#include"
Windows.h"
math.h"
time.h>
//几个全局变量,存放读入图像的位图数据、宽、高、颜色表及每像素所占位数(比特)
//此处定义全局变量主要为了后面的图像数据访问及图像存储作准备
unsignedchar*pBmpBuf;
//读入图像数据的指针
intbmpWidth;
//图像的宽
intbmpHeight;
//图像的高
intimgSpace;
//图像所需空间
RGBQUAD*pColorTable;
//颜色表指针
intbiBitCount;
//图像类型
charstr[100];
//文件名称
intNum[300];
//各灰度值出现的次数
floatFeq[300];
//各灰度值出现的频率
unsignedchar*lpBuf;
//指向图像像素的指针
unsignedchar*m_pDib;
//存放打开文件的DIB
intNodeNum;
//Huffman树总节点个数
intNodeStart;
//Huffman树起始节点
structNode{//Huffman树节点
intcolor;
//记录叶子节点的灰度值(非叶子节点为-1)
intlson,rson;
//节点的左右儿子(若没有则为-1)
intnum;
//节点的数值(编码依据)
intmark;
//记录节点是否被用过(用过为1,没用过为0)
}node[600];
charCodeStr[300][300];
//记录编码值
intCodeLen[300];
//编码长度
boolImgInf[8000000];
//图像信息
intInfLen;
//图像信息长度
/***********************************************************************
*函数名称:
*readBmp()
*
*函数参数:
*char*bmpName-文件名字及路径
*返回值:
*0为失败,1为成功
*说明:
给定一个图像文件名及其路径,读图像的位图数据、宽、高、颜色表及每像素
*位数等数据进内存,存放在相应的全局变量中
***********************************************************************/
boolreadBmp(char*bmpName)
//FILE*fp=fopen("
E:
\ProgramFiles\program\Huffman\1.bmp"
"
FILE*fp=fopen(bmpName,"
if(fp==0)
fread(pBmpBuf,1,lineByte*bmpHeight,fp);
保存信息
//二进制转十进制
intChange2to10(intpos){
inti,j,two=1;
for(i=pos+7;
i>
=pos;
i--){
j+=two*ImgInf[i];
two*=2;
//保存Huffman编码树
intsaveInfo(char*writeP
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Huffman 编码 解码