您的位置:首页 > 运维架构

RGB转jpeg(opencv或IJG)

2016-03-01 10:48 337 查看
RGB转jpeg的方法:先对图像进行预处理,然后DCT变换,量化,然后进行编码,huffman编码或其它编码,就可以转换成jpg了。下面主要讲解使用opencv保存jpg图像,或使用IJG库保存jpg图像,使用opencv保存jpg图像的函数如下:

   
CVAPI(int) cvSaveImage(constchar*
filename,constCvArr* image,

                          constint* 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: