四叉树有损位图压缩处理程序示例
四叉树有损位图压缩处理程序示例
发布时间:2016-12-28 来源:查字典编辑
摘要:一个四叉树课设程序,可以对24位图进行压缩,应用于windows平台。main.c复制代码代码如下:#include"bmp.h"intma...

一个四叉树课设程序,可以对24位图进行压缩,应用于windows平台。

main.c

复制代码 代码如下:

#include "bmp.h"

int main()

{

BITMAPFILEHEADER fileHeader;

BITMAPINFOHEADER infoHeader;

FILE* pfin1 =fopen("test.bmp","rb");

FILE* pfout1 = fopen("test1.dat" , "wb");

FILE* pfout2 = fopen("test2.bmp" , "wb");

FILE* pfin2 =fopen("test1.dat","rb");

quadtree_t T=NULL;

//Read the Bitmap file header;

fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,pfin1);

//Read the Bitmap info header;

fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,pfin1);

//为简化代码,只处理24位彩色

if( infoHeader.biBitCount == 24 )

{

//int size = infoHeader.biWidth*infoHeader.biHeight;

int size = infoHeader.biWidth*infoHeader.biHeight;

RGB *img=NULL;

img=(RGB*)malloc(infoHeader.biHeight*infoHeader.biWidth*sizeof(RGB));

if(img!=NULL)

{

fread( img , sizeof(RGB) , size , pfin1 );

fwrite( &fileHeader , sizeof(fileHeader) , 1 , pfout1 );

fwrite( &infoHeader , sizeof(infoHeader) , 1 , pfout1 );

treediv(&T,0,infoHeader.biWidth-1,0,infoHeader.biHeight-1,pfout1,img,infoHeader.biWidth);

free(img);

//将修改后的图片保存到文件

fclose(pfin1);

fclose(pfout1);

}

//将图片解压后还原

openbmp(pfin2,pfout2);

fclose(pfin2);

fclose(pfout2);

}

return 0;

}

func.c

复制代码 代码如下:

#include "bmp.h"

//像素阀值函数

int ComparePixel(short int width1,short int width2,short int height1,short int height2,RGB *img,short int W)

{

RGB MAX,MIN;

int flag,i,j,clr1,clr2;

clr1=width2-width1;

clr2=height2-height1;

if(clr1<3||clr2<3) //此函数用于判断分割的图片大小是否宽度与高度为1;

{

flag=1;

return flag;

}

MAX.b=MIN.b=img[height1*W+width1].b;

MAX.g=MIN.b=img[height1*W+width1].g;

MAX.r=MIN.b=img[height1*W+width1].r;

flag=1;

for(i=height1;i<=height2;i++)

{

for(j=width1;j<=width2;j++)

{

if(img[i*W+j].r>MAX.r) MAX.r=img[i*W+j].r;

else if(img[i*W+j].r<MIN.r) MIN.r=img[i*W+j].r;

if(img[i*W+j].g>MAX.g) MAX.g=img[i*W+j].g;

else if(img[i*W+j].g<MIN.g) MIN.g=img[i*W+j].g;

if(img[i*W+j].b>MAX.b) MAX.b=img[i*W+j].b;

else if(img[i*W+j].b<MIN.b) MIN.b=img[i*W+j].b;

if((MAX.r-MIN.r>0x14)||(MAX.g-MIN.g>0x14)||(MAX.b-MIN.b>0x14)) //阀值设为0xc0;

{

flag=0;

return flag; //flag为标志位,决定是否继续分割图像

}

}

}

return flag;

}

//四叉树分割函数(该函数的实参有待调整,特别是范围那几个参数)!!!!!!!!!

int treediv(quadtree_t *T,short int width1,short int width2,short int height1,short int height2,FILE* S,RGB *img,short int W)

{

int flag=0;

RGB *div;

div=img;

short int x1=width1,x2=width2;

short int y1=height1,y2=height2;

int w=W;

flag=ComparePixel(x1,x2,y1,y2,div,w);

if(!((*T) = (quadnode_t*)malloc(sizeof(quadnode_t))))

return 0;

if(!flag) //若标志位为假,则进行递归分割

{

treediv(&((*T)->sub[0]),width1,(width1+width2)/2,height1,(height1+height2)/2,S,div,w);

treediv(&((*T)->sub[1]),(width1+width2)/2+1,width2,height1,(height1+height2)/2,S,div,w);

treediv(&((*T)->sub[2]),(width1+width2)/2+1,width2,(height1+height2)/2+1,height2,S,div,w);

treediv(&((*T)->sub[3]),width1,(width1+width2)/2,(height1+height2)/2+1,height2,S,div,w);

}

else //如果标志位为真,则将该范围内像素统一

{

st.rgb.r=(*T)->pixel.r=(img[width1+height1*W].r+img[width2+height2*W].r)/2;

st.rgb.g=(*T)->pixel.g=(img[width1+height1*W].g+img[width2+height2*W].g)/2;

st.rgb.b=(*T)->pixel.b=(img[width1+height1*W].b+img[width2+height2*W].b)/2;

st.x1=width1; st.x2=width2; st.y1=height1; st.y2=height2;

fwrite( &st , sizeof(BLOCK) , 1 , S );

*T=NULL; free(*T);

//num++;

}

return 0;

}

//图像解压函数

void openbmp(FILE *S1,FILE *S2)

{

BITMAPFILEHEADER fileHeader;

BITMAPINFOHEADER infoHeader;

fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,S1);

fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,S1);

BLOCK sti;

int p,q;

int size = infoHeader.biWidth*infoHeader.biHeight;

//RGB pic[infoHeader.biHeight][infoHeader.biWidth];

RGB *pic;

pic=(RGB*)malloc(infoHeader.biHeight*infoHeader.biWidth*sizeof(RGB));

while(!feof(S1))

{

fread(&sti,sizeof(BLOCK),1,S1);

int w1=sti.x1;int w2=sti.x2;

int h1=sti.y1;int h2=sti.y2;

for(p=h1;p<=h2;p++)

{

for(q=w1;q<=w2;q++)

{

pic[p*infoHeader.biWidth+q].b=sti.rgb.b;

pic[p*infoHeader.biWidth+q].g=sti.rgb.g;

pic[p*infoHeader.biWidth+q].r=sti.rgb.r;

}

}

}

fwrite( &fileHeader , sizeof(fileHeader) , 1 , S2 );

fwrite( &infoHeader , sizeof(infoHeader) , 1 , S2 );

fwrite(pic,sizeof(RGB),size,S2);

}

bmp.h

复制代码 代码如下:

#ifndef BMP_H_INCLUDED

#define BMP_H_INCLUDED

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

/*像素类型*/

typedef struct{

BYTE b;

BYTE g;

BYTE r;

}RGB;

/*四叉树结点类型*/

typedef struct quadnode_t

{

RGB pixel;

struct quadnode_t *sub[4];

}quadnode_t,*quadtree_t;

/*像素文件存储结构*/

typedef struct block

{

RGB rgb;

short int x1,x2,y1,y2;

}BLOCK;

BLOCK st;

//static int num=0;

int treediv(quadtree_t *T,short int width1,short int width2,short int height1,short int height2,FILE* S,RGB *img,short int W);

int ComparePixel(short int width1,short int width2,short int height1,short int height2,RGB *img,short int W);

void openbmp(FILE *S1,FILE *S2);

#endif // BMP_H_INCLUDED

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新C语言学习
热门C语言学习
编程开发子分类