1.老师简直丧心病狂,居然上机作业布置这个,简直了
2.参考网上资料,课本,终于写完了
3.首先将彩色图片转化为位图bmp,然后哈夫曼编码压缩,然后解压缩,我真是醉了(有什么用)
4.具体用法
BMPToGray 彩色图片转灰度图
encode 压缩
decode方法解压缩
彩色图片必须是位图(bmp),不是的格式工厂转化
然后每一个方法输入两个参数,分别为输入文件名,和输出文件名
5.源码
compressor.h文件
#pragma pack(1)
typedef struct BMPHeader
{
unsigned char bfType[2];//文件格式
unsigned long bfSize;//文件大小
unsigned short bfReserved1;//保留
unsigned short bfReserved2;
unsigned long bfOffBits; //DIB数据在文件中的偏移量
}Header;
typedef struct BMPInfo
{
unsigned long biSize;//该结构的大小
long biWidth;//文件宽度
long biHeight;//文件高度
unsigned short biPlanes;//平面数
unsigned short biBitCount;//颜色位数
unsigned long biCompression;//压缩类型
unsigned long biSizeImage;//DIB数据区大小
long biXPixPerMeter;
long biYPixPerMeter;
unsigned long biClrUsed;//多少颜色索引表
unsigned long biClrImporant;//多少重要颜色
}Info;
typedef struct RGBQuad
{
unsigned char rgbBlue; //蓝色分量亮度
unsigned char rgbGreen;//绿色分量亮度
unsigned char rgbRed;//红色分量亮度
unsigned char rgbReserved;
}Quad;
#pragma pack()
typedef struct{
unsigned char uch;
unsigned long weight;
}TmpNode;
typedef struct Node{
unsigned char uch;
unsigned long weight;
char *code; // 字符对应的哈夫曼编码
int parent, lchild, rchild;
Node(){parent=0;}
} HufNode,*HufTree;
class Compressor
{
private:
unsigned char RGBData[4000][3];
unsigned char GrayData[4000];
FILE * fpBMP,* fpGray;
Header * header;
Info * info;
Quad * quad;
public:
int BmpToGray(const char *,const char *);
int decode(const char *,const char *);
int encode(const char *,const char *);
int openFile(const char *,const char *);
void select(HufNode*,unsigned int,int *);
void createTree(HufNode *,unsigned int,unsigned int);
void createCode(HufNode *,unsigned);
void closeFile();
};
#include
#include
#include
#include
#include"compressor.h"
using namespace std;
int Compressor::openFile(const char *in,const char *out){
if(!(fpBMP=fopen(in,"rb")))
{
printf("打开文件失败\n");
return 0;
}
if(!(fpGray=fopen(out,"wb")))
{
printf("创建文件失败\n");
return 0;
}
return 1;
}
void Compressor::select(HufNode *huf_tree, unsigned int n, int *s1)
{
unsigned long m=ULONG_MAX;
for(int i = 0;ib.weight;
}
int Compressor::encode(const char * in,const char *out){
if(!openFile(in,out)) return 0;
TmpNode *tmp_nodes= new TmpNode[256];
for(int i=0;i<256;i++){
tmp_nodes[i].weight=0;
tmp_nodes[i].uch=(unsigned char)i;
}
unsigned char tmp_char;
unsigned long file_len=0,node_num;
unsigned int char_kinds=256;
HufNode *huf_tree;
while(fread(&tmp_char,1,1,fpBMP)){
file_len++;
tmp_nodes[tmp_char].weight++;
}
sort(tmp_nodes,tmp_nodes+256,cmp);
for(int i=0;i= 8)
{
char_temp =0;
for(int i = 0; i < 8; ++i)
char_temp=(char_temp<<1)|(code_buf[i]-'0');
fwrite((char *)&char_temp, sizeof(unsigned char), 1, fpGray); // 将字节对应编码存入文件
strcpy(code_buf, code_buf+8); // 编码缓存去除已处理的前八位
}
fread((char *)&char_temp, sizeof(unsigned char), 1, fpBMP); // 每次读取8bits
}
unsigned int l=strlen(code_buf);
if(l)
{
char_temp =0;
for(int i = 0; i biBitCount=8;
info->biSizeImage=( (info->biWidth*3+3)/4 ) * 4*info->biHeight;
header->bfOffBits = sizeof(Header)+sizeof(Info)+256*sizeof(Quad);
header->bfSize = header->bfOffBits + info->biSizeImage;
int i,j,k;
for(i=0;i<256;i++)
quad[i].rgbBlue=quad[i].rgbGreen=quad[i].rgbRed=i;
fwrite(header,sizeof(Header),1,fpGray);
fwrite(info,sizeof(Info),1,fpGray);
fwrite(quad,sizeof(Quad),256,fpGray);
for (i=0;ibiHeight;i++ )
{
for(j=0;j<(info->biWidth+3)/4*4;j++)
{
fread(&RGBData[j],1,3,fpBMP);
GrayData[j]=RGBData[j][0] * 0.114 +RGBData[j][1] * 0.587 +RGBData[j][2] * 0.299;
}
fwrite(GrayData,j,1,fpGray);
}
delete header;
delete info;
delete [] quad;
closeFile();
return 1;
}
void test(){
Compressor compressor;
compressor.BmpToGray("in.bmp","out.bmp");
cout<<"彩色图片转化为灰度图完成"<