四叉樹有損位圖壓縮處理程序示例
一個(gè)四叉樹課設(shè)程序,可以對(duì)24位圖進(jìn)行壓縮,應(yīng)用于windows平臺(tái)。
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);
//為簡(jiǎn)化代碼,只處理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"
//像素閥值函數(shù)
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) //此函數(shù)用于判斷分割的圖片大小是否寬度與高度為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)) //閥值設(shè)為0xc0;
{
flag=0;
return flag; //flag為標(biāo)志位,決定是否繼續(xù)分割圖像
}
}
}
return flag;
}
//四叉樹分割函數(shù)(該函數(shù)的實(shí)參有待調(diào)整,特別是范圍那幾個(gè)參數(shù))!!!!!!!!!
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) //若標(biāo)志位為假,則進(jìn)行遞歸分割
{
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 //如果標(biāo)志位為真,則將該范圍內(nèi)像素統(tǒng)一
{
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;
}
//圖像解壓函數(shù)
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;
/*四叉樹結(jié)點(diǎn)類型*/
typedef struct quadnode_t
{
RGB pixel;
struct quadnode_t *sub[4];
}quadnode_t,*quadtree_t;
/*像素文件存儲(chǔ)結(jié)構(gòu)*/
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
您可能感興趣的文章
- 01-10深入二叉樹兩個(gè)結(jié)點(diǎn)的最低共同父結(jié)點(diǎn)的詳解
- 01-10深入理解二叉樹的非遞歸遍歷
- 01-10深入遍歷二叉樹的各種操作詳解(非遞歸遍歷)
- 01-10判斷整數(shù)序列是否為二元查找樹的后序遍歷結(jié)果的解決方法
- 01-10探討:C++實(shí)現(xiàn)鏈?zhǔn)蕉鏄?用非遞歸方式先序,中序,后序遍歷二叉樹
- 01-10如何在二叉樹中找出和為某一值的所有路徑
- 01-10深入linux下遍歷目錄樹的方法總結(jié)分析
- 01-10先序遍歷二叉樹的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)深入解析
- 01-10二叉搜索樹的插入與刪除(詳細(xì)解析)
- 01-10二叉查找樹的插入,刪除,查找


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery