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
#include
#include
#include
#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;
}