1、从www.ijg.org下载源码,解压后得到文件夹jpeg-8d
2、在文件夹里新建jconfig.h文件,将jconfig.vc里的内容拷到jconfig.h中
3、编译.
Run->CMD->进入到C:\Program Files\Microsoft Visual Studio 8\VC\bin目录(不同的VC编译器目录也不一样)下
->运行vcvars32.bat文件,此时
-->到把目录定到我们的代码地方->nmake /f makefile.vc
这样就生成了我们的libjpeg.lib了
例子代码:
http://www.rayfile.com/zh-cn/files/c6a7051e-8e7a-11e1-a698-0015c55db73d/
一、建立编译环境
把libjpeg.lib 添加到你的项目中,并指定lib链接目录与头文件链接目录,我的为 ..\jpeg-8d
二、压缩步骤
1、申请并初始化jpeg压缩对象,同时要指定错误处理器
struct jpeg_compress_struct jcs; // 声明错误处理器,并赋值给jcs.err域 struct jpeg_error_mgr jem; jcs.err = jpeg_std_error(&jem); jpeg_create_compress(&jcs);
2、指定压缩后的图像所存放的目标文件,注意,目标文件应以二进制模式打开
if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return -1; } jpeg_stdio_dest(&cinfo, outfile);
3、设置压缩参数,主要参数有图像宽、高、色彩通道数(1:索引图像,3:其他),色彩空间(JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像),压缩质量等,如下:
cinfo.image_width = width; // 为图的宽和高,单位为像素 cinfo.image_height = height; cinfo.input_components = depth; // 在此为1,表示灰度图, 如果是彩色位图,则为3 cinfo.in_color_space = JCS_GRAYSCALE; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像 // jpeg_set_defaults函数一定要等设置好图像宽、高、 // 色彩通道数计色彩空间四个参数后才能调用, // 因为这个函数要用到这 四个值, // 调用jpeg_set_defaults函数后,jpeglib库采用默认的设置对图像进行压缩 jpeg_set_defaults(&cinfo); // jpeg_set_defaults函数一定要等设置好图像宽、高、 // 色彩通道数计色彩空间四个参数后才能调用, // 因为这个函数要用到这 四个值,调用jpeg_set_defaults函数后, // jpeglib库采用默认的设置对图像进行压缩 jpeg_set_quality(&cinfo, 80 /*JPEG_QUALITY*/, TRUE );
4、上面的工作准备完成后,就可以压缩了,压缩过程非常简单,首先调用 jpeg_start_compress,然后可以对每一行进行压缩,也 可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,压缩完成后,记得要调用jpeg_finish_compress函数,如下:
jpeg_start_compress(&cinfo, TRUE); row_stride = width; // 在图像缓冲区里每天的SAMPLEs while (cinfo.next_scanline < cinfo.image_height)// 对每一次进行压缩 { row_pointer[0] = & data[cinfo.next_scanline * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); // 压缩完成后,记得要调用jpeg_finish_compress函数
5、最后就是释放压缩工作过程中所申请的资源了,主要就是jpeg压缩对象,由于在本例中我是直接用的局部变量,所以只需调用jpeg_destroy_compress这个函数即可,如下:
jpeg_destroy_compress(&cinfo);
有网友反映我的代码运行后的效果只是一片的灰色,这里向大家道歉,因为自己没有去验证过。
于是我在原有的基础上参考了文章: http://blog.csdn.net/chenyujing1234/article/details/7730478
后,修改我的代码如下。
虽然不是全部的灰色,但还是出现图像失真的问题。有待改进。。。。
//#include <Windows.h> #include <stdlib.h> #include <stdio.h> #include <afxwin.h> #include "jpeglib.h" // 参考 http://space.itpub.net/7232789/viewspace-714150 int main() { FILE *fd; // 源文件句柄 FILE *outfile; // 目标文件句柄 int ret; unsigned char *data; long sizeImage; char *filename = "palm2.jpg"; int width = 670; int height = 503; int depth = 3; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; // 声音错误处理器,并赋值给jcs.err域 JSAMPROW row_pointer[1]; // 一行位图, 指向JSAMPLE row[s] int row_stride; // 每一行的字节数 sizeImage = width*height*sizeof(unsigned char)*4; data = (unsigned char*)malloc(sizeImage); fd = fopen("palm.bmp", "rb");// 打开要压缩的源文件 if(!fd) { printf("ERROR1: Can not open the image.\n"); free(data); return -1; } //int sizeHead = sizeof(BITMAPINFOHEADER); //fseek(fd, 1078, SEEK_SET); // 跳过bmp文件头,直接读取掌纹图像数据 ret = fread(data, sizeof(unsigned char)*sizeImage, 1, fd); if(ret == 0) { if(ferror(fd)) { printf("\nERROR2: Can not read the pixel data.\n"); free(data); fclose(fd); return -1; } } //RGB顺序调整 for (int i=0, j=0; j < width*height*4; i+=3, j+=4) { *(data+i)=*(data+j+2); *(data+i+1)=*(data+j+1); *(data+i+2)=*(data+j); } cinfo.err = jpeg_std_error(&jerr); // 指定错误处理器 // 第一步: // 初始化jpeg压缩对象 jpeg_create_compress(&cinfo); // 第二步: // 指定压缩后的图像所存放的目标文件,目标文件以二进制模式打开 if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return -1; } jpeg_stdio_dest(&cinfo, outfile); // 第三步: // 设置压缩参数,主要参数有图像宽、高、色彩通道数(1:索引图像,3:其他), // 色彩空间(JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像),压缩质量 cinfo.image_width = width; // 为图的宽和高,单位为像素 cinfo.image_height = height; cinfo.input_components = depth; // 在此为1,表示灰度图, 如果是彩色位图,则为3 cinfo.in_color_space = JCS_RGB; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像 // jpeg_set_defaults函数一定要等设置好图像宽、高、 // 色彩通道数计色彩空间四个参数后才能调用, // 因为这个函数要用到这 四个值, // 调用jpeg_set_defaults函数后,jpeglib库采用默认的设置对图像进行压缩 jpeg_set_defaults(&cinfo); // jpeg_set_defaults函数一定要等设置好图像宽、高、 // 色彩通道数计色彩空间四个参数后才能调用, // 因为这个函数要用到这 四个值,调用jpeg_set_defaults函数后, // jpeglib库采用默认的设置对图像进行压缩 jpeg_set_quality(&cinfo, 50 , TRUE ); // 第四步: // 上面的工作准备完成后,就可以压缩了, // 压缩过程非常简单,首先调用 jpeg_start_compress, // 然后可以对每一行进行压缩,也 可以对若干行进行压缩, // 甚至可以对整个的图像进行一次压缩 jpeg_start_compress(&cinfo, TRUE); row_stride = width*depth; // 在图像缓冲区里每天的SAMPLEs while (cinfo.next_scanline < cinfo.image_height)// 对每一次进行压缩 { //这里我做过修改,由于jpg文件的图像是倒的,所以改了一下读的顺序 //这是原代码: //row_pointer[0] = &data[cinfo.next_scanline * row_stride]; row_pointer[0] = &data[(cinfo.image_height - cinfo.next_scanline - 1) * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); // 压缩完成后,记得要调用jpeg_finish_compress函数 // 第五步: // 最后就是释放压缩工作过程中所申请的资源了, // 主要就是jpeg压缩对象 jpeg_destroy_compress(&cinfo); free(data); fclose(fd); fclose(outfile); return 0; }