LIBJPEG

        在一个项目中需要将一些图像数据保存成文件,出现的问题是数据量非常大,文件高达几百兆以及上G,所以需要对数据进行压缩,Google了一下,发现了LIBJPEG这个开源库,在项目中使用后效果非常好,文件一下子减小了很多。

        http://www.ijg.org/是这个库的网站,从上面可以下载最新的源代码以及编译好的库,是一个Independent JPEG Group的组织(简称IJG)开发的一个开源免费库,下一个版本将在2013年发布。

        但在使用的时候存在一个问题,LIBJPEG无论压缩还是解压缩操作的时候都是对FILE指针来操作,如果我有一个图像数据,无法直接对图像数据进行压缩。还好有源代码,很多人对源代码进行了改造,使得可以支持对内存数据进行压缩和解压缩,具体过程在这就不详细叙述,后面会给出一些参考网站。


这个库使用起来非常简单,下面给出我写的一个简单的压缩类和解压类:

#pragma once
#include <stdio.h>
extern "C"
{
	#include "jpeglib.h"
};

class CJpegCompress
{
public:
	CJpegCompress(void);
	~CJpegCompress(void);

public:
	//初始化压缩参数
	//buffer:压缩后的数据内存,pSize输出压缩后的数据大小
	//nWidth,nHeight,nChannel宽度高度和通道数
	void InitCompressVar(char* buffer,int* pSize,int nWidth,int nHeight,int nChannel);

	//压缩
	//buffer:输入原始数据,nStride:图像stride
	void CompressBuffer(unsigned char* buffer,int nStride);

protected:
	struct jpeg_compress_struct jcs;
	struct jpeg_error_mgr jem;
};
#include "StdAfx.h"
#include "JpegCompress.h"

#pragma comment(lib,"..\\lib\\MyJpegLib.lib")

CJpegCompress::CJpegCompress(void)
{
	jcs.err = jpeg_std_error(&jem);
	jpeg_create_compress(&jcs);
}

CJpegCompress::~CJpegCompress(void)
{
	jpeg_destroy_compress(&jcs);
}

//nChannel = 1 或 3
void CJpegCompress::InitCompressVar(char* buffer,int* pSize,int nWidth,int nHeight,int nChannel)
{
	jpeg_stdio_dest(&jcs, buffer,pSize);

	jcs.image_width = nWidth;    // 为图的宽和高,单位为像素 
	jcs.image_height = nHeight;

	jcs.input_components = nChannel;   // 在此为1,表示灰度图, 如果是彩色位图,则为3 
	jcs.in_color_space = nChannel == 1 ? JCS_GRAYSCALE:JCS_RGB; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像

	jpeg_set_defaults(&jcs); 
	jpeg_set_quality (&jcs, 80, true);
}

void CJpegCompress::CompressBuffer(unsigned char* buffer,int nStride)
{
	 jpeg_start_compress(&jcs, TRUE);
	 JSAMPROW row_pointer[1];   // 一行位图
	 int row_stride;      // 每一行的字节数
	 row_stride = nStride;

	 while (jcs.next_scanline < jcs.image_height) 
	 {
		 row_pointer[0] = &buffer[(jcs.image_height-1-jcs.next_scanline) * row_stride];
		 jpeg_write_scanlines(&jcs, row_pointer, 1);
	 }
	 jpeg_finish_compress(&jcs);
}
#pragma once
#include <stdio.h>
extern "C"
{
#include "jpeglib.h"
};

class CJpegDecompress
{
public:
	CJpegDecompress(void);
	~CJpegDecompress(void);

public:
	void GetImageInfo(char* inBuffer,int size,int& nwidth,int& nHeight,int& nChannel);

	void DeCompressBuffer(unsigned char* Outbuffer);

protected:
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jem;
};

#include "StdAfx.h"
#include "JpegDeCompress.h"

#pragma comment(lib,"..\\lib\\MyJpegLib.lib")

CJpegDecompress::CJpegDecompress(void)
{
	cinfo.err = jpeg_std_error(&jem);
	jpeg_create_decompress(&cinfo);
}

CJpegDecompress::~CJpegDecompress(void)
{
	 jpeg_destroy_decompress(&cinfo);
}

void CJpegDecompress::GetImageInfo(char* inBuffer,int size,int& nwidth,int& nHeight,int& nChannel)
{
	 jpeg_stdio_src(&cinfo,inBuffer,size);
	 jpeg_read_header(&cinfo, TRUE);
	 nwidth = cinfo.image_width;
	 nHeight = cinfo.image_height;
	 nChannel = cinfo.num_components;
}

void CJpegDecompress::DeCompressBuffer(unsigned char* Outbuffer)
{
	jpeg_start_decompress(&cinfo);
	JSAMPROW row_pointer[1];
	while (cinfo.output_scanline < cinfo.output_height)
	{
		row_pointer[0] = &Outbuffer[(cinfo.output_height - cinfo.output_scanline-1)*cinfo.image_width*cinfo.num_components];
		jpeg_read_scanlines(&cinfo,row_pointer ,1);
	}
	jpeg_finish_decompress(&cinfo);
}

         使用起来都非常方便简单,具体调用示例就不列出了,这里用的库是我经过改造之后的LIBJPEG库,如果有谁需要,本人可以将改造后的LIBJPEG代码无私奉献出去,省去大家改造的麻烦,欢迎大家交流沟通,我的邮箱:[email protected]
        

参考资料:         

         http://blog.csdn.net/achellies/article/details/4238056
         http://www.ijg.org/
         http://blog.chinaunix.net/space.php?uid=16400726&do=blog&id=2746316







   

你可能感兴趣的:(struct,header,Google,Class,buffer,Components)