四叉树有损位图压缩处理程序示例

一个四叉树课设程序,可以对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

(0)

相关推荐

  • 四叉树有损位图压缩处理程序示例

    一个四叉树课设程序,可以对24位图进行压缩,应用于windows平台. main.c 复制代码 代码如下: #include "bmp.h" int main(){BITMAPFILEHEADER fileHeader;BITMAPINFOHEADER infoHeader;FILE* pfin1 =fopen("test.bmp","rb");FILE* pfout1 = fopen("test1.dat" , "

  • django在保存图像的同时压缩图像示例代码详解

    假设我们有一个非常简单的Post模型,它将是一个图像及其描述, from django.db import models class Post(models.Model): text = models.TextField() image = models.ImageField(upload_to='images/') 但是我们要优化图像大小,这将由我们Post的image字段指出. 这样做有充分的理由-它有助于更快地加载网站/应用程序并减少我们的服务器存储. 在使用Django之前,首先让我们简

  • python多线程下信号处理程序示例

    本文实例为大家分享了python多线程下信号处理程序示例的具体代码,供大家参考,具体内容如下 下面是一个网上转载的实现思路,经过验证,发现是可行的,就记录下来. 思路 python多线程中要响应Ctrl+C的信号以杀死整个进程,需要: 1.把所有子线程设为Daemon: 2.使用isAlive()函数判断所有子线程是否完成,而不是在主线程中用join()函数等待完成: 3.写一个响应Ctrl+C信号的函数,修改全局变量,使得各子线程能够检测到,并正常退出. 源码 #!/usr/bin/env p

  • python 实现压缩和解压缩的示例

    一.说明 压缩和解压缩是日常常用的操作,不管是windows上图形界面的操作,还是linux上用命令来进行压缩解压缩,总的而言都还是比较方便的. 但用代码来实现就没做过,近期也得实现代码压缩与解压缩操作,所以就抽时间来研究一下. 二.zip文件压缩和解压缩实现 import os import zipfile # 函数功能是zip_file_list所有文件,和zip_dir_list所有目录下的所有文件,被压缩到一个zip_file_name的压缩文件中 def my_zip_function

  • C# 进行图片压缩的示例代码(对jpg压缩效果最好)

    直接上代码 public static class ImageCompress { /// <summary> /// 图片压缩 /// </summary> /// <param name="imagePath">图片文件路径</param> /// <param name="targetFolder">保存文件夹</param> /// <param name="qualit

  • vue使用exif获取图片旋转,压缩的示例代码

    <template> <div> <input type="file" id="upload" accept="image" @change="upload" /> </div> </template> <script> export default { data() { return { picValue:{}, headerImage:'' }; },

  • python 实现图片批量压缩的示例

    项目中大量用到图片加载,由于图片太大,加载速度很慢,因此需要对文件进行统一压缩 一:导入包 from PIL import Image import os 二:获取图片文件的大小 def get_size(file): # 获取文件大小:KB size = os.path.getsize(file) return size / 1024 三:拼接输出文件地址 def get_outfile(infile, outfile): if outfile: return outfile dir, suf

  • java实现文件上传下载和图片压缩代码示例

    分享一个在项目中用的到文件上传下载和对图片的压缩,直接从项目中扒出来的:) 复制代码 代码如下: package com.eabax.plugin.yundada.utils; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.

  • java生成压缩文件示例代码

    代码: 复制代码 代码如下: import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream; import org.apache.tools.zip.ZipEntry;import org.apache.tools.zip.ZipOutputStream; /**  * @project: Test  * @author

  • C++Zip压缩解压缩示例(支持递归压缩)

    第三方函数.头文件.测试工程下载地址:http://pan.baidu.com/s/1gSfKo 复制代码 代码如下: // 文件名: ZipFunction.h#pragma once#include "zip.h"#include "unzip.h" namespace ZipUtils{    // ---------------------------------------------------------------------------------

随机推荐