RGB
转
jpeg
的方法:先对图像进行预处理,然后
DCT
变换,量化,然后进行编码,
huffman
编码或其它编码,就可以转换成
jpg
了。下面主要讲解使用
opencv
保存
jpg
图像,或使用
IJG
库保存
jpg
图像,使用
opencv
保存
jpg
图像的函数如下:
CVAPI(
int
)
cvSaveImage
(
const
char
*
filename
,
const
CvArr
*
image
,
const
int
*
params CV_DEFAULT
(
0
)
);
第三个参数可以设置压缩的质量
int params[3]
params[0] = CV_IMWRITE_JPEG_QUALITY;
params[1] = 85;//
设置
s
压缩度
params[2] = 0;
把
params
传入就可以了
。
举例如下:
//cvSaveImage(str.GetBuffer(0), (IplImage*)pRGBBuff);
使用
IJG
进行压缩的方法如下:
首先下载
IJG
库,下载的网站是
http://www.ijg.org
,然后对下载的源码进行编译,编译可以参考它的文档,我下载的为
jpegsr8c
,按照它的文档,只能编译出
vc6.0
和
vs2010
的版本库,我没有安装
vs2010
的软件,所以使用
vc6.0
编译出来的库,发现不能使用,原因可能是
vc6.0
编译的是单线程的东东,但是我使用的是多线程的东西。所以我使用
vs2008
重新对源码进行编译:编译方法如下:
一、建立自己的libjpeg工程
为了修改后编译方便,也为了以后在VC 环境下容易使用libjpeg库,我们按以下步骤将libjpeg转换为VC环境下的工程。
1
、在VC环境下重新建立一个空的static library工程,工程名为libjpeg,此处注意,新建工程不要包含mfc,不要预编译头文件;
2
、然后将libjpeg下的
jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c
jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c
jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c
jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c
jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c
jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c
jquant2.c jutils.c jmemmgr.c
jchuff.h jconfig.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h
jpegint.h jpeglib.h jversion.h 等文件拷贝到新工程的文件夹下,并将.c文件改名为.cpp;
3
、将所有的源文件及头文件添加到新建的工程中;
4
、编译新工程,此时就可以生成libjpeg.lib了。
编译完库后就可以使用了。
/*===================================================================================
function:
jpeg
压缩
input:
1:
生成的文件名,2:bmp
的指针,3:位图宽度,4:位图高度,5:颜色深度
return:
int
description:
bmp
的像素格式为(RGB)
===================================================================================*/
int
savejpeg
(
char
*
filename
,
unsigned
char
*
bits
,
int
width
,
int
height
,
int
depth
)
{
struct
jpeg_compress_struct
cinfo
;
struct
jpeg_error_mgr
jerr
;
FILE
*
outfile
;
JSAMPROW
row_pointer
[1];
int
row_stride
;
cinfo
.
err
=
jpeg_std_error
(&
jerr
);
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
);
cinfo
.
image_width
=
width
;
//image width and height, in pixels
cinfo
.
image_height
=
height
;
cinfo
.
input_components
= 3;
// of color components per pixel
cinfo
.
in_color_space
=
JCS_RGB
;
//colorspace of input image
jpeg_set_defaults
(&
cinfo
);
jpeg_set_quality
(&
cinfo
,
JPEG_QUALITY
,
TRUE
);
//limit to baseline-JPEG values
jpeg_start_compress
(&
cinfo
,
TRUE
);
row_stride
=
width
*
depth
;
// JSAMPLEs per row in image_buffer
while
(
cinfo
.
next_scanline
<
cinfo
.
image_height
) {
//row_pointer[0] = & bits[cinfo.next_scanline * row_stride];
row_pointer
[0] = &
bits
[(
cinfo
.
image_height
–
cinfo
.
next_scanline
– 1) *
row_stride
];
(
void
)
jpeg_write_scanlines
(&
cinfo
,
row_pointer
, 1);
}
jpeg_finish_compress
(&
cinfo
);
fclose
(
outfile
);
jpeg_destroy_compress
(&
cinfo
);
return
0;
}
用该函数进行
jpg
压缩时,发现颜色是反的,因为
RGB
,
bmp
是按照
BGRBGR
排列的,而
IJG
是按照
RGBRGBRGB
这样的格式排列的,所以必须对
RGB
数据进行逆转,才能满足要求。逆转的函数如下:
void
RGBReverse
(
BYTE
*
pRgbBuf
)
{
BYTE
Tmp
;
if
(
pRgbBuf
==
NULL
)
{
return
;
}
for
(
int
i
=0;
i
<
IMAGE_SIZE_H
*
IMAGE_SIZE_V
*3;
i
+=3)
{
Tmp
=*(
pRgbBuf
+
i
);
*(
pRgbBuf
+
i
)=*(
pRgbBuf
+
i
+2);
*(
pRgbBuf
+
i
+2)=
Tmp
;
}
return
;
}