RGB轉jpeg(opencv或IJG)

smilestone322發表於2016-03-01

RGBjpeg的方法:先對影象進行預處理,然後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.0vs2010的版本庫,我沒有安裝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壓縮時,發現顏色是反的,因為RGBbmp是按照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;

}

相關文章