C++实现图片压缩算法(哈夫曼编码)

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



compressor.cpp文件

#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<<"彩色图片转化为灰度图完成"<

好运,晚安。。。

你可能感兴趣的:(C++实现图片压缩算法(哈夫曼编码))