首页 > 学院 > 开发设计 > 正文

libjpeg库的使用(VC6.0环境)

2019-11-06 08:12:11
字体:
来源:转载
供稿:网友

之前的libjpeg6的版本,只能对针对图像文件进行压缩和解压缩,后来网上出现了很多通过修改源代码实现内存中图像压缩解压缩的方法。针对的都是老版本。现在的libjpeg9的版本,已经将这个重要的函数加进来了。 jpeg_mem_dest、jpeg_mem_src   对应的是对内存中图像的操作。EXTERN(void) jpeg_mem_dest JPP((j_comPRess_ptr cinfo,      unsigned char ** outbuffer,      unsigned long * outsize));EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,     unsigned char * inbuffer,     unsigned long insize));利用上面的函数,不用修改源代码,可以直接在内存中压缩解压缩了。是不是很happy呢,这可要感谢那些辛苦更新这些开源库的小伙伴们!这一篇文章,将主要讲windows下的这个库的使用。linux下的使用,稍后会在另一篇文章中细说。好了废话不多说。上干货。我的开发环境系统是Windows xpIDE:VC6.0第一步下载libjpeg 下载地址:http://www.ijg.org/(若下载不顺畅可在http://download.csdn.net/detail/renyongyuan/9769507直接下载)下载jpegsr9a.zip这个文件。解压这个压缩包到一个纯英文目录下。我的位置是E:/C_example/jpeg-9a第二步打开cmd命令行窗口,将目录切换到你刚才解压的那个目录下面如图libjpeg库的使用(VC6.0环境)然后输入下面的命令NMAKE /f makefile.vc  setup-vc6第三步打开刚才解压的目录找到jpeg.dsw这个工程。点击Build。就可以生成lib文件。需要注意的地方,jpeg.dsw这个工程中 工程->设置->c/c++下拉菜单code generation 中的Processor选项和Use run-time library选项,这两个选项必须要你自己的工程设置成相同的。以你自己的工程为准,修改jpeg.dsw工程中的上述两个选项。这么做的是确保编译出来的lib库文件和你自己的工程能够兼容,否则将会出现下面的错误warning LNK4098: defaultlib "libcmt.lib" conflicts with use of other libs; use /NODEFAULTLIB:library第四步还是刚才的解压目录,刚才build,会产生一个Release文件夹,这里面就是生成的lib文件将里面的jpeg.lib文件和解压目录下的jconfig.h、jmorecfg.h、jpeglib.h四个文件放在一个新建的名字为libjpeg文件夹下面。把这个文件夹拷贝到你的工程目录下面第五步在你要调用这个库的工程中添加下面的语句extern "C" {#include "jpeglib.h"#include }#pragma comment(lib, "libjpeg/jpeg.lib") 然后你就可以调用下面的代码进行解压缩了。struct my_error_mgr {struct jpeg_error_mgr pub;jmp_buf setjmp_buffer;};把下面的程序拷贝到你的工程中,直接调用jpeg_decompress这个函数就能实现解压缩。typedef struct my_error_mgr * my_error_ptr;METHODDEF(void)my_error_exit (j_common_ptr cinfo){my_error_ptr myerr = (my_error_ptr) cinfo->err;(*cinfo->err->output_message) (cinfo);longjmp(myerr->setjmp_buffer, 1);}GLOBAL(int) jpeg_decompress(unsigned char *inbuf,unsigned char *outbuf,unsigned int size){struct jpeg_decompress_struct cinfo;struct my_error_mgr jerr;JSAMPARRAY buffer; int row_stride;  cinfo.err = jpeg_std_error(&jerr.pub);jerr.pub.error_exit = my_error_exit;if (setjmp(jerr.setjmp_buffer)) {jpeg_destroy_decompress(&cinfo);return 0;}jpeg_create_decompress(&cinfo);jpeg_mem_src(&cinfo,inbuf,size);jpeg_read_header(&cinfo, TRUE);jpeg_start_decompress(&cinfo);row_stride =cinfo.output_width * cinfo.output_components;//计算图片每行需要的内存大小,单位字节buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);//以上这些都是固定的调用步骤,不知道每句的意思的话千万别改动while (cinfo.output_scanline < cinfo.output_height){jpeg_read_scanlines(&cinfo,buffer,1);//解压出一行数据memcpy(outbuf,buffer[0],row_stride);//将解压出的数据拷贝至outbufoutbuf += row_stride;//指针前移一行}//以上这些都是固定的调用步骤,不知道每句的意思的话千万别改动jpeg_finish_decompress(&cinfo);jpeg_destroy_decompress(&cinfo);return 1;}另外附录一段话,来自http://bbs.witech.com.cn/thread-8131-1-1.html“解压时,libjpeg是以图片的一行为单位解压的,也就是图片水平的一条线,jpeg存储时左上角是坐标原点,bmp存储时左下角是原点,因此转化时要把上下顺序颠倒一下才是正确的,所以outbuf传入的是最后一个字节的地址,从最后一个字节往前顺序拷贝jpg解压缩出来的数据才能得到正确的图片。解压出来的bmp文件是24位图片,每个像素占用8位,因此如果图片大小为640*480,则outbuf大小应该为921654 = 640*480*3+54,其中54位为bmp文件头,则传入的outbuf应该是开辟的内存空间起始地址+921654,至于bmp头的制作我就不讲了,大家自己看吧,就那么点东西”根据这段话,调用的时候outbuf应该是指向输出缓存区的最后一个字节,但是我在实际使用的时候,解压出来的图像时反的,所以我就把outbuf设置为指向输出缓存区的第一个字节了,然后把程序中的下面语句   outbuf -= row_stride;//指针前移一行   jpeg_read_scanlines(&cinfo,buffer,1);解压出一行数据   memcpy(outbuf,buffer[0],row_stride);将解压出的数据拷贝至outbuf修改为jpeg_read_scanlines(&cinfo,buffer,1);//解压出一行数据memcpy(outbuf,buffer[0],row_stride);//将解压出的数据拷贝至outbufoutbuf += row_stride;//指针前移一行改完之后发现图像正常了。ps如果碰到下面的问题fatal error:C1083:can not open include file:jpeglib.h:no such file or directory

请查看你的工程

Project->setting->c/c++/preprocessor页面里面的

Additional include directory这个栏目,如果是空的,需要添加一个头文件的目录。

请填写libjpeg(就是放头文件那个目录名字)

完整的工程下载


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表